jvm-内存大小设置简述 -读《java-performance》

《Java Performance》 下载 tomcat

Java Performance》做者 Charlie Hunt / Binu John 介绍

        Charlie Hunt 现任Salesforce公司的性能工程架构师。曾任Oracle公司首席JVM性能工程师,负责HotSpot Java虚拟机和Java SE类库性能的改进。Charlie拥有美国伊利诺伊理工大学的计算机科学硕士学位、爱荷华州立大学的计算机科学学士学位。
        Binu John 是世界上最大的社交网站建立平台Ning.com的高级性能工程师。他目前的职责是着力改善Ning平台的性能和扩展性,以支持每个月数百万PV的访问量。Binu拥有美国爱荷华大学生物医学工程和计算机科学硕士学位。架构

书中jvm推荐配置片断

一、计算存活对象大小(P274)
jvm

二、各内存区域配置(P275)
工具

我的总结

一、获取老年代存活对象大小性能

  • 使用 jmap -histo:live pid 获取内存快照,此时会发生Full GC(此方式会影响线上服务的使用,若是使用此方式,能够将改此应用降级后再执行),观察老年代存活对象大小,关于jmap等其余jdk工具更多使用方式能够参考 JDK内置工具使用网站

  • 开启GC日志打印,例配置jvm参数 -XX:+PrintGC 观察屡次Full GC后老年代存活对象的大小取平均值为准操作系统

二、设置jvm内存区域大小.net

      约定:以 old_size 表示通过Full GC后老年代存活对象大小3d

  • 整个堆大小设置为 old_size 在的 3-4 倍
  • 堆中新生代大小为 old_size 的 1-1.5倍
  • 堆中老年代大小为 old_size 的 2-3倍,默认新生代与老年代的比例为 1:2 ,不冲突
  • 老年代(jdk8为元数据MetaSpace)大小为 old_size 的 1.2-1.5倍

三、配置实践日志


      首先观察一下一个已经运行了33天的vm的gc情况:
      在33天内发生了1151次minor gc,每次12323/1151=10.7ms,天天35次左右 ; 6次full gc,每次(12.823-12.323)/6=83.3ms,6天才一次,收集器新生代为默认的CMS,每次发生的缘由都是Eden区没法分配内存,综上,内存基本没什么压力低,几天一次的stw几乎对应用无任何影响,咱们能够适当的让此jvm活跃起来,减小内存等资源的空闲,把cpu充分的利用起来,再来看一下内存使用的状况:


      在未强制执行Full gc前:

      能够得到总的堆内存大小为:MaxHeapSize=946M,新生代与老年代最大分别为9461/3=315M、9462/3=630M,此时老年代使用大小为118M


在强制full gc后:

      老年代存活对象大小为:91M,那么整个堆设置大小在 91 x 4=364M,永久代(元数据)在 91 x 1.5=136M


      修改tomcat配置以下:

      修改后堆内存分配,没有意外


      查询gc状况

      发如今应用启动阶段会发生屡次minor gc与少许full GC,我想缘由也比较明显,在应用启动阶段,须要建立不少对象,这些对象在新生代达到必定大小就会伴随着minor gc的发生,full gc也如此...


四、更多
      如何设置各区域内存,除了此推荐配置外,还须要根据应用特性和硬件环境等其余因素来考虑,例如在32位计算机中,操做系统对进程内存大小是有限制的,设想一个进程限制为2G,那么对应用的堆内存又该如何配置呢?除了划分堆内存,直接内存溢出也会发生OutOfMemoryError。在64位计算机中,单应用若是自己体积就比较大,老年代对象比较多,发生一次Full GC所花费的时间可能会达到几秒甚至几十秒,此时又有什么比较好的解决方式呢?一些简单可行的方法就是设置较大内存来使Full GC尽可能少的发生,在流量较少的阶段强制Full GC或重启等,在代码层面咱们能够尽可能少的建立大对象,使对象在新生代朝生夕死,减小老年代的压力...

      关于内存该如何设置?须要根据这些已有经验与应用特性来综合考虑...

相关文章
相关标签/搜索