JVM优化总结

    首先明确java堆分为perm和heap, 本文只讨论heap空间。

JVM优化总结_第1张图片

概念说明

Eden存放新生成的对象, 它内部的对象生命周期不超过1次Minor GC。

S0、S1的S是Survivor的缩写, 它用于存放MinorGC后幸存,又不满足进入Old Generation条件的对象。为什么要有S0和S1?因为这里用的垃圾回收算法是复制算法, 具体可以查看http://my.oschina.net/xiaoqqq/blog/387327

Old Generation一般称作老年代、旧生代, 它里面存放的是生命周期超过MaxTenuringThreshold值得对象和大对象。

Minor GC即新生代GC, 它是jvm回收Eden和S0、S1内存活对象的GC过程, 他的触发条件是Eden内存不够分配新的对象。

Full GC即全局GC, 每次执行Full GC都会暂停所有用户线程,减少Full GC的执行次数是优化很重要的部分。它的触发条件是Minor GC将对象往Old Generation中移动时发现Old Generation空间不足。

   

参数介绍

在使用单线程回收器、多线程回收器、并行回收、CMS回收器的情况下(7种垃圾收集器除了G1), 通常minor GC要远快于Full GC。这是很明显的,minor GC只回收新生代, 通常都是些生命周期短的小对象, 而Full GC则回收整个heap,包括老年代中一些寿命很长的对象和大对象。

    各个代的大小设置直接决定了minor GC和Full GC的触发时机, 在代大小的优化上, 主要参数包括-Xms、-Xmx、-Xmn、-XX:SurvivorRatio、-XX:MaxTenuringThreshold。

-Xms和-Xmx分别表示堆heap可以使用的最小内存和最大内存, 优化时通常将这两个值设置为相同的值, 以避免JVM不断为他们分配内存空间。
-Xmn表示新生代内存大小, 新生代中Eden、S0、S1三个区域的比例可以通过-XX:SurvivorRatio来设置, 如果-Xmn的值为10M, -XX:SurvivorRatio的值为8, 就说明Eden区域内存块大小为8M, S0、S1分别为1M。(Eden用于存放)
-XX:MaxTenuringThreshold表示新生代对象经历多少次MinorGC后进入老年代,也就是新生代对象生存周期,此参数默认值一般为15, 且只在串行GC时有效。

其他参数到这里查看http://my.oschina.net/xiaoqqq/blog/384808


监控GC

1. JVM启动参数中添加-verbose:gc -XX:+PrintGCTimeStamps -XX:+PrintGCDetails -Xloggc:./gc.log

以下内容为使用jdk7时输出, jdk版本不同, 启动参数不同显示内容会有些差异。

10.160: [GC10.160: [DefNew: 16384K->2048K(18432K), 0.0169596 secs] 16384K->16120K(131072K), 0.0618775 secs] [Times: user=0.02 sys=0.00, real=0.06 secs] 
10.186: [GC10.186: [DefNew: 18432K->2048K(18432K), 0.0167307 secs] 32504K->31731K(131072K), 0.0168543 secs] [Times: user=0.02 sys=0.00, real=0.02 secs] 
10.206: [GC10.207: [DefNew: 18432K->2047K(18432K), 0.0174237 secs] 48115K->48028K(131072K), 0.0175884 secs] [Times: user=0.03 sys=0.02, real=0.03 secs] 
10.227: [GC10.227: [DefNew: 18431K->2047K(18432K), 0.0157971 secs] 64412K->64398K(131072K), 0.0159248 secs] [Times: user=0.01 sys=0.00, real=0.01 secs] 
10.246: [GC10.246: [DefNew: 18431K->2048K(18432K), 0.0204069 secs] 80782K->80756K(131072K), 0.0205314 secs] [Times: user=0.02 sys=0.00, real=0.02 secs] 
10.269: [GC10.269: [DefNew: 18432K->2048K(18432K), 0.0174500 secs] 97140K->97116K(131072K), 0.0175259 secs] [Times: user=0.02 sys=0.00, real=0.01 secs] 
10.289: [Full GC10.289: [Tenured: 95068K->107060K(112640K), 0.0388235 secs] 107283K->107060K(131072K), [Perm : 2488K->2488K(21248K)], 0.0389029 secs] [Times: user=0.03 sys=0.00, real=0.03 secs] 
15.319: [GC15.319: [DefNew: 16384K->16384K(18432K), 0.0000187 secs]15.319: [Tenured: 107060K->16622K(112640K), 0.0181551 secs] 123444K->16622K(131072K), [Perm : 2488K->2488K(21248K)], 0.0182582 secs] [Times: user=0.02 sys=0.00, real=0.02 secs] 
Heap
 def new generation   total 18432K, used 656K [0x00000000f2c00000, 0x00000000f4000000, 0x00000000f4000000)
  eden space 16384K,   4% used [0x00000000f2c00000, 0x00000000f2ca4290, 0x00000000f3c00000)
  from space 2048K,   0% used [0x00000000f3c00000, 0x00000000f3c00000, 0x00000000f3e00000)
  to   space 2048K,   0% used [0x00000000f3e00000, 0x00000000f3e00000, 0x00000000f4000000)
 tenured generation   total 112640K, used 16622K [0x00000000f4000000, 0x00000000fae00000, 0x00000000fae00000)
   the space 112640K,  14% used [0x00000000f4000000, 0x00000000f503b948, 0x00000000f503ba00, 0x00000000fae00000)
 compacting perm gen  total 21248K, used 2495K [0x00000000fae00000, 0x00000000fc2c0000, 0x0000000100000000)
   the space 21248K,  11% used [0x00000000fae00000, 0x00000000fb06fc88, 0x00000000fb06fe00, 0x00000000fc2c0000)
No shared spaces configured.

DefNew是垃圾回收期类型, 即serial young collector, 因为这里在启动参数中指定了-XX:+UseSerialGC, 如果不指定则默认使用ParNewGC, 这里的值就是PSYoungGen。

以上日志说明jvm进行了8次垃圾回收, 其中7次MinorGC, 1次FullGC。FullGC行中显示本次全局回收耗时为0.0389029 secs

2. 使用jstat:

jstat -gc -h20 -t 9076 1s > jstat.log

-h20表示每输出20行,打印一次表头,无此参数时只在监控开始打印一次表头
-t表示在每行前面加入JVM时间戳timestamp

9076是进程id
1s表示每隔1秒打印一次监控结果

优化原则

1. 新生代不能太小也不能太大。 太小会导致MinorGC频繁,有些大对象直接进入老年代。 太大会导致老年代减小, 从而导致Full GC频繁。注意: 看本文最开始的图片。

以下为同一段测试程序, 新生代设置的大小不同, gc的情况:


#-Xms130M -Xmx130M -Xmn120M -XX:+UseSerialGC
Timestamp        S0C    S1C    S0U    S1U      EC       EU        OC         OU       PC     PU    YGC     YGCT    FGC    FGCT     GCT   
           34.4 12288.0 12288.0  0.0    0.0   98304.0  96510.2   10240.0    10240.0   21248.0 2488.3      1    0.047   2      0.109    0.157
#-Xms130M -Xmx130M -Xmn20M -XX:+UseSerialGC
Timestamp        S0C    S1C    S0U    S1U      EC       EU        OC         OU       PC     PU    YGC     YGCT    FGC    FGCT     GCT   
           30.8 2048.0 2048.0  0.0    0.0   16384.0    0.0     112640.0   107060.6  21248.0 2488.3      6    0.146   1      0.049    0.195

重点查看YGC(新生代gc次数)、YGCT(新生代gc耗时)、FGC(full gc次数)、FGCT(full gc耗时) 这4列

通常推荐新生代占heap空间的1/3

2. 根据情况, 合理分配Survivor空间。

3. 合理指定新生代对象的生命周期。



你可能感兴趣的:(JVM优化总结)