高吞吐量调整
UseAdaptiveSizePolicy
UseAdaptiveSizePolicy 策略路径
UseAdaptiveSizePolicy
1、-XX:MaxGCPauseMillis=nnn :不能设置过小,会阻碍吞吐量,如果不设置,暂停时间依赖heap中活动数据量。
2、-XX:GCTimeRatio=nnn 不超过应用运行时间的1 / (1 + nnn) 用在垃圾回收上。缺省99。垃圾回收时间不应该超过整体时间的1%
JVM微调调试方法
内存大小影响
1、大内存:
1. 降低GC执行次数。 2.增加每次GC执行的时间。
2、小内存:
1.增加了GC执行次数 2.降低每次GC执行的时间。
如果Full GC能够在1秒内完成,10G也是合适的。
Jstat 监视微调
jstat -gcutil 21891 250 7
21891是Java的pid, 250表示间隔几秒 7表示采样7次
S0 S1 E O P YGC YGCT FGC FGCT GCT
12.44 0.00 27.20 9.49 96.70 78 0.176 5 0.495 0.672
12.44 0.00 62.16 9.49 96.70 78 0.176 5 0.495 0.672
12.44 0.00 83.97 9.49 96.70 78 0.176 5 0.495 0.672
0.00 7.74 0.00 9.51 96.70 79 0.177 5 0.495 0.673
0.00 7.74 23.37 9.51 96.70 79 0.177 5 0.495 0.673
0.00 7.74 43.82 9.51 96.70 79 0.177 5 0.495 0.673
0.00 7.74 58.11 9.51 96.71 79 0.177 5 0.495 0.673
Minor GC :YGC年轻代GC发生了78次,YGCT是GC发生的时间累计0.176。
FULL GC发生了5次,累计0.495, 每次是0.495/5
http://www.cubrid.org/blog/dev-platform/how-to-monitor-java-garbage-collection/
如果GC执行时间在一秒以上,需要GC微调,如果在0.1-0.3之间则不需要
需要微调的案例
微调前检查内存大小分配
jstat –gccapacity
NGCMN NGCMX NGC S0C S1C EC OGCMN OGCMX OGC OC PGCMN PGCMX PGC PC YGC FGC
212992.0 212992.0 212992.0 21248.0 21248.0 170496.0 1884160.0 1884160.0 1884160.0 1884160.0 262144.0 262144.0 262144.0 262144.0 54 5
新生代是 212,992 KB,老生代是1,884,160 KB
新生代:老生代是1:9, 调整NewRatio
NewRatio=2
NewRatio=3
NewRatio=4
如果其中一个设置没有FULL GC发生,就是合适新生代和老生代的大小。
随着新生代内存减小,其GC时间缩短:
NewRatio=2: 45 ms
NewRatio=3: 34 ms
NewRatio=4: 30 ms
内存输出结构:
S0 S1 E O P YGC YGCT FGC FGCT GCT
8.61 0.00 30.67 24.62 22.38 2424 30.219 0 0.000 30.219
年轻代发生了2424次,而FullGC没有一次发生,存在大量临时对象都是新生代毁灭。
Jstat参数说明
JVM优化参数
JAVA_OPTS="$JAVA_OPTS -verbose:gc -XX:+PrintGCDetails -XX:+PrintTenuringDistribution -Xloggc:/home/jdon/jdongc.log -server -Xms1536m -Xmx1664m -XX:NewSize=768m -XX:MaxNewSize=896m -XX:+UseAdaptiveGCBoundary -XX:MaxGCPauseMillis=250 -XX:+UseAdaptiveSizePolicy -XX:+DisableExplicitGC -XX:ParallelGCThreads=4 -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:+CMSIncrementalMode -XX:CMSInitiatingOccupancyFraction=80 -XX:+CMSClassUnloadingEnabled
最大新生代GC暂停时间是250毫秒,在这个基础上JVM自动调整尽量满足吞吐量。
[GC 2016.468: [ASParNew: 686991K->42743K(711316K), 0.1310080 secs] 713706K->74888K(1422668K) icms_dc=0 , 0.1324500 secs]
S0 S1 E O P YGC YGCT FGC FGCT GCT
0.00 64.80 93.53 4.52 66.34 7 0.619 7 2.381 3.000
如果响应时间还是不够快?
1、响应延迟和吞吐量是一对矛盾,而吞吐量主要标志是内存大小。
2、降低NewSize大小, 降低survivor空间。
3、降低进入老生代reduce的门槛,因为缓存Hold住大量长生命对象,让这些对象进口进入老生代。而老生代的CMS很少暂停。
CMS
CMS并不进行内存压实compact,所以,会导致碎片。而碎片也会导致暂停。
三个垃圾回收机制的比较,语法如下:
使用GCViewer观察,结果如下 单位是毫秒:
Parallel | CMS | G1 | |
---|---|---|---|
Total GC pauses | 20 930 | 18 870 | 62 000 |
Max GC pause | 721 | 64 | 50 |
并行GC ( - XX:+ UseParallelOldGC ) 。在30多分钟的测试时间内,用并行收集器 GC暂停花了接近21秒。最长停顿了721毫秒。因此,我们以此为基准: GC降低了吞吐量为总运行时间的1.1 %。最坏情况下的延迟为721ms 。
CMS ( - XX:+ UseConcMarkSweepGC ) 同样30分钟,因为GC我们失去了不到19秒 。相比并行GC吞吐量明智的。延迟另一方面已显著改善 - 最坏情况下的延迟时间减少10倍以上!来自GC的最大暂停时间我们现在面临的只是64ms。
最闪亮的GC算法 - G1 ( - XX:+ UseG1GC ) 。在同样的测试,,我们看到的结果吞吐量问题比较严重。这一次,我们的应用程序花费超过一分钟等待GC来完成。比较这与CMS中的开销只有1% ,我们现在面对接近的吞吐量3.5 %的效果。但如果你真的不关心的吞吐量,而是想挤出最后那么一点延迟 - 比CMS提高20%左右 - 用G1看到的最长GC暂停服用仅50毫秒。
结论:CMS仍然是最好的“默认”选项。 G1的吞吐量仍然差那么多,得到的延迟通常是不值得的。
Heap size | Total GC pauses GC暂停 | Throughput吞吐量 |
---|---|---|
-Xmx300m | 207.48s | 92.25% |
-Xmx384m | 54.13s | 97.97% |
-Xmx720m | 20.52s | 99.11% |
-Xmx1,440m | *11.37s | *99.55% |