-XX:+PrintTenuringDistribution 赠送银弹: -XX:SurvivorRatio
作用:输出显示在survivor空间里面有效的对象的岁数情况。
{Heap before GC invocations=0 (full 0):
par new generation total 1887488K, used 1677824K [0x00000006e0c00000, 0x0000000760c00000, 0x0000000760c00000)
eden space 1677824K, 100% used [0x00000006e0c00000, 0x0000000747280000, 0x0000000747280000)
from space 209664K, 0% used [0x0000000747280000, 0x0000000747280000, 0x0000000753f40000)
to space 209664K, 0% used [0x0000000753f40000, 0x0000000753f40000, 0x0000000760c00000)
concurrent mark-sweep generation total 2097152K, used 0K [0x0000000760c00000, 0x00000007e0c00000, 0x00000007e0c00000)
concurrent-mark-sweep perm gen total 512000K, used 22205K [0x00000007e0c00000, 0x0000000800000000, 0x0000000800000000)
2018-02-06T13:29:54.526+0800: 6.958: [GC2018-02-06T13:29:54.526+0800: 6.958: [ParNew2018-02-06T13:29:54.584+0800: 7.016: [SoftReference, 0 refs, 0.0000450 secs]2018-02-06T13:29:54.584+0800: 7.016: [WeakReference, 1074 refs, 0.0001630 secs]2018-02-06T13:29:54.584+0800: 7.017: [FinalReference, 67745 refs, 0.1348760 secs]2018-02-06T13:29:54.719+0800: 7.152: [PhantomReference, 0 refs, 0.0000180 secs]2018-02-06T13:29:54.719+0800: 7.152: [JNI Weak Reference, 0.0000090 secs]
Desired survivor size 107347968 bytes, new threshold 1 (max 30)
- age 1: 157548032 bytes, 157548032 total
: 1677824K->154017K(1887488K), 0.1942010 secs] 1677824K->154017K(3984640K), 0.1942870 secs] [Times: user=0.20 sys=0.08, real=0.19 secs]
Heap after GC invocations=1 (full 0):
par new generation total 1887488K, used 154017K [0x00000006e0c00000, 0x0000000760c00000, 0x0000000760c00000)
eden space 1677824K, 0% used [0x00000006e0c00000, 0x00000006e0c00000, 0x0000000747280000)
from space 209664K, 73% used [0x0000000753f40000, 0x000000075d5a8560, 0x0000000760c00000)
to space 209664K, 0% used [0x0000000747280000, 0x0000000747280000, 0x0000000753f40000)
concurrent mark-sweep generation total 2097152K, used 0K [0x0000000760c00000, 0x00000007e0c00000, 0x00000007e0c00000)
concurrent-mark-sweep perm gen total 512000K, used 22205K [0x00000007e0c00000, 0x0000000800000000, 0x0000000800000000)
}
其中-XX:+PrintTenuringDistribution只是丰富了gclog部分如下:
Desired survivor size 107347968 bytes, new threshold 1 (max 30)
- age 1: 157548032 bytes, 157548032 total
: 1677824K->154017K(1887488K), 0.1942010 secs] 1677824K->154017K(3984640K), 0.1942870 secs] [Times: user=0.20 sys=0.08, real=0.19 secs]
描述信息:
Survivor对象年龄,最大值设置的是30,实际计算后的阀值是1。
Survivor大小,Desired survivor size指的是整个Survivor的1/2 107347968byte也就是 from or to 的大小,所以例子中的Survivor大小是204mb 对象阀值是1,从这个例子中可以看出进入survivor的对象比survivor预留空间大,所以会有对象到老年代中。这时最好要调整-XX:SurvivorRatio来设置合理的Survivor
Survivor中存活对象157mb,切年龄是1。
赠送银弹
额外赠送-XX:SurvivorRatio=8 含义:eden/suvivor=8 ,其中survivor包含from、to。
eg:yong区设定2g,-XX:NewSize=2g ,那么,from = 2g/(8+2) ,也就是说yong区会被分成10分,eden区占8分,survivor占2份,这也能看出比值越大survivor被稀释的越严重。比值越小survivor分到的空间更大。
以上面log为例,计算出合理的-XX:SurvivorRatio ,可以确定survivor为160mb*2为合理区域,所以假设比值为x,eden=320x,yong区总共 2g=320x+320,所以比值x=(2g-320)/320 ,x近似=5。
继续分析log中的age
截取运行过一段时间的日志分析下:
{Heap before GC invocations=11 (full 0):
par new generation total 1887488K, used 1716581K [0x00000006e0c00000, 0x0000000760c00000, 0x0000000760c00000)
eden space 1677824K, 100% used [0x00000006e0c00000, 0x0000000747280000, 0x0000000747280000)
from space 209664K, 18% used [0x0000000753f40000, 0x00000007565196a8, 0x0000000760c00000)
to space 209664K, 0% used [0x0000000747280000, 0x0000000747280000, 0x0000000753f40000)
concurrent mark-sweep generation total 2097152K, used 23205K [0x0000000760c00000, 0x00000007e0c00000, 0x00000007e0c00000)
concurrent-mark-sweep perm gen total 512000K, used 49938K [0x00000007e0c00000, 0x0000000800000000, 0x0000000800000000)
2018-02-06T14:21:29.610+0800: 3102.042: [GC2018-02-06T14:21:29.610+0800: 3102.042: [ParNew2018-02-06T14:21:29.639+0800: 3102.072: [SoftReference, 0 refs, 0.0000400 secs]2018-02-06T14:21:29.639+0800: 3102.072: [WeakReference, 9421 refs, 0.0005540 secs]2018-02-06T14:21:29.640+0800: 3102.072: [FinalReference, 4196 refs, 0.0044150 secs]2018-02-06T14:21:29.644+0800: 3102.077: [PhantomReference, 4 refs, 0.0000080 secs]2018-02-06T14:21:29.644+0800: 3102.077: [JNI Weak Reference, 0.0000090 secs]
Desired survivor size 107347968 bytes, new threshold 16 (max 30)
- age 1: 4345400 bytes, 4345400 total
- age 2: 2436856 bytes, 6782256 total
- age 3: 676112 bytes, 7458368 total
- age 4: 2323952 bytes, 9782320 total
- age 5: 599616 bytes, 10381936 total
- age 6: 563656 bytes, 10945592 total
- age 7: 567656 bytes, 11513248 total
- age 8: 815480 bytes, 12328728 total
- age 9: 527672 bytes, 12856400 total
- age 10: 3956032 bytes, 16812432 total
- age 11: 16575184 bytes, 33387616 total
: 1716581K->49462K(1887488K), 0.0345690 secs] 1739786K->72667K(3984640K), 0.0349280 secs] [Times: user=0.12 sys=0.00, real=0.04 secs]
Heap after GC invocations=12 (full 0):
par new generation total 1887488K, used 49462K [0x00000006e0c00000, 0x0000000760c00000, 0x0000000760c00000)
eden space 1677824K, 0% used [0x00000006e0c00000, 0x00000006e0c00000, 0x0000000747280000)
from space 209664K, 23% used [0x0000000747280000, 0x000000074a2cd8a0, 0x0000000753f40000)
to space 209664K, 0% used [0x0000000753f40000, 0x0000000753f40000, 0x0000000760c00000)
concurrent mark-sweep generation total 2097152K, used 23205K [0x0000000760c00000, 0x00000007e0c00000, 0x00000007e0c00000)
concurrent-mark-sweep perm gen total 512000K, used 49938K [0x00000007e0c00000, 0x0000000800000000, 0x0000000800000000)
}
格式:- age 年龄: 处于当前年龄段的对象大小 总大小(各个年龄段是累计的)
总结6:
-XX:+PrintTenuringDistribution这个参数对于设置-XX:MaxTenuringThreshold有很大帮助,阀值需要长时间观察对象分布,设置合理即可。
-XX:MaxTenuringThreshold设置过大问题:原本应该晋升对象到survivor区,直到survivor区溢出,一旦溢出发生,Eden+Svuvivor中对象将不再依据年龄全部提升到老年代,这样对象老化的机制就失效了
-XX:MaxTenuringThreshold设置过小:eden区的对象会陆续送入old区,对象移动本身就是开销,cms老年代回收还会造成碎片化。
传送门jvm-对象动态年龄计算规则