GC调优实战
在什么情况下需要进行GC调优?
关于GC的性能主要有两个指标:
1.吞吐量 throughput (工作时间不算gc的时间/总的时间)
2.响应时间(暂停时间)gc发生时app对外是无法响应的
那么什么时候需要gc调优
a: 系统访问慢
体现在整体慢,部分慢
- 仔细了解自己的应用,如果用了缓存,那么年老代应该大一些,缓存的HashMap不应该无限制长,建议采用LRU算法的Map做缓存,LRUMap的最大长度也要根据实际情况设定。
- 采用并发回收时,年轻代小一点,年老代要大,因为年老大用的是并发回收,即使时间长点也不会影响其他程序继续运行,网站不会停顿
调优的基本步骤是什么?
1.获取到GC日志
2.使用gcseay或者gcviewer分析日志文件
3.查看各种gc的次数和时间
4.查看吞吐量、延迟(响应时间)等信息
5.进行gc调优
1.内存的带下调整
2.gc垃圾收集器的调整
3.gc垃圾器的相关配置参数调整
6.返回第一步。gc调优是个不管测试的过程,一个参数的设置可能就带来不一样的gc效果。
调优实战
- jvm配置一:
<jvm-arg>-Xmx7550m</jvm-arg>
<jvm-arg>-Xms7550m</jvm-arg>
<jvm-arg>-Xss256k</jvm-arg>
<jvm-arg>-XX:PermSize=256m</jvm-arg>
<jvm-arg>-XX:MaxPermSize=512m</jvm-arg>
<jvm-arg>-XX:ParallelGCThreads=20</jvm-arg>
<jvm-arg>-XX:+UseConcMarkSweepGC</jvm-arg>
<jvm-arg>-XX:+UseParNewGC</jvm-arg>
<jvm-arg>-XX:+DisableExplicitGC</jvm-arg>
<jvm-arg>-javaagent:wagent.jar</jvm-arg>
<jvm-arg>-XX:+PrintGCDetails</jvm-arg>
<jvm-arg>-Xloggc:E:\gc.log</jvm-arg>
对应的gc日志:
gc1.log
- jvm配置二:
<jvm-arg>-Xmx3550m</jvm-arg>
<jvm-arg>-Xms3550m</jvm-arg>
<jvm-arg>-Xss256k</jvm-arg>
<jvm-arg>-XX:PermSize=256m</jvm-arg>
<jvm-arg>-XX:MaxPermSize=512m</jvm-arg>
<jvm-arg>-XX:ParallelGCThreads=20</jvm-arg>
<jvm-arg>-XX:+UseConcMarkSweepGC</jvm-arg>
<jvm-arg>-XX:+UseParNewGC</jvm-arg>
<jvm-arg>-XX:+DisableExplicitGC</jvm-arg>
<jvm-arg>-javaagent:wagent.jar</jvm-arg>
<jvm-arg>-XX:+PrintGCDetails</jvm-arg>
<jvm-arg>-Xloggc:E:\gc.log</jvm-arg>
对应的gc日志:
gc2.log
- jvm配置三:
<jvm-arg>-Xmx3550m</jvm-arg>
<jvm-arg>-Xms3550m</jvm-arg>
<jvm-arg>-Xss256k</jvm-arg>
<jvm-arg>-XX:PermSize=100m</jvm-arg>
<jvm-arg>-XX:MaxPermSize=200m</jvm-arg>
<jvm-arg>-XX:ParallelGCThreads=20</jvm-arg>
<jvm-arg>-XX:+UseConcMarkSweepGC</jvm-arg>
<jvm-arg>-XX:+UseParNewGC</jvm-arg>
<jvm-arg>-XX:+DisableExplicitGC</jvm-arg>
<jvm-arg>-javaagent:wagent.jar</jvm-arg>
<jvm-arg>-XX:+PrintGCDetails</jvm-arg>
<jvm-arg>-Xloggc:E:\gc.log</jvm-arg>
对应的gc日志:
gc3.log
- jvm配置四:
<jvm-arg>-Xmx3550m</jvm-arg>
<jvm-arg>-Xms3550m</jvm-arg>
<jvm-arg>-Xss256k</jvm-arg>
<jvm-arg>-XX:PermSize=256m</jvm-arg>
<jvm-arg>-XX:MaxPermSize=512m</jvm-arg>
<jvm-arg>-XX:ParallelGCThreads=20</jvm-arg>
<jvm-arg>-XX:+UseG1GC</jvm-arg>
<jvm-arg>-XX:+DisableExplicitGC</jvm-arg>
<jvm-arg>-javaagent:wagent.jar</jvm-arg>
<jvm-arg>-XX:+PrintGCDetails</jvm-arg>
<jvm-arg>-Xloggc:E:\gc4.log</jvm-arg>
对应的gc日志:
gc4.log
22.43% of GC time (i.e 58 ms) is caused by 'Metadata GC Threshold'.
- jvm配置五:
<jvm-arg>-Xmx7550m</jvm-arg>
<jvm-arg>-Xms7550m</jvm-arg>
<jvm-arg>-Xss256k</jvm-arg>
<jvm-arg>-XX:PermSize=100m</jvm-arg>
<jvm-arg>-XX:MaxPermSize=200m</jvm-arg>
<jvm-arg>-XX:ParallelGCThreads=20</jvm-arg>
<jvm-arg>-XX:+UseG1GC</jvm-arg>
<jvm-arg>-XX:+DisableExplicitGC</jvm-arg>
<jvm-arg>-javaagent:wagent.jar</jvm-arg>
<jvm-arg>-XX:+PrintGCDetails</jvm-arg>
<jvm-arg>-Xloggc:E:\gc5.log</jvm-arg>
对应的gc日志:
gc5.log
29.29% of GC time (i.e 66 ms) is caused by 'Metadata GC Threshold'.
- jvm配置六:
<jvm-arg>-Xmx7550m</jvm-arg>
<jvm-arg>-Xms7550m</jvm-arg>
<jvm-arg>-Xss256k</jvm-arg>
<jvm-arg>-XX:PermSize=256m</jvm-arg>
<jvm-arg>-XX:MaxPermSize=512m</jvm-arg>
<jvm-arg>-XX:ParallelGCThreads=20</jvm-arg>
<jvm-arg>-XX:+UseG1GC</jvm-arg>
<jvm-arg>-XX:+DisableExplicitGC</jvm-arg>
<jvm-arg>-javaagent:wagent.jar</jvm-arg>
<jvm-arg>-XX:+PrintGCDetails</jvm-arg>
<jvm-arg>-Xloggc:E:\gc5.log</jvm-arg>
对应的gc日志:
gc6.log
32.65% of GC time (i.e 68 ms) is caused by 'Metadata GC Threshold'.
调优结果分析
一、以下是gcViewer分析出的结果统计
log文件 | 吞吐量 | 响应时间(min/max) | newgc | oldgc | fullgc |
---|---|---|---|---|---|
log1 | 85.03 | 0.0129/0.17256 | 1 | 1 | 0 |
log2 | 83.43 | 0.01347/0.2232 | 2 | 1 | 0 |
log3 | 81.56 | 0.01232/0.21427 | 2 | 1 | 0 |
log4 | 96.93 | 0.00224/0.074642 | 6 | 2 | 0 |
log5 | 94.67 | 0.00258/0.05686 | 3 | 2 | 0 |
log6 | 94.11 | 0.00265/0.06221 | 2 | 2 | 0 |
二、以下是gcEasy分析出的结果统计
log文件 | 吞吐量 | 响应时间(max/av) | newgc | oldgc | fullgc |
---|---|---|---|---|---|
log1 | 83.943 | 170 /83 | |||
log2 | 82.077 | 220/110 | |||
log3 | 80.149 | 210/120 | |||
log4 | 97.002 | 50/14 | |||
log5 | 95.201 | 60/16 | |||
log6 | 94.274 | 60/19 |
分析结果:
1.将log1和log6做对比:
- log1采用的是CMS垃圾收集器
- log6采用的是个G1垃圾收集器
- 其他配置不变
很明显的可以发现,使用G1垃圾收集器在吞吐量和响应时间都有大幅度的提升
2.将log1和log2做对比:
- 二者均是采用CMS垃圾收集器
- log1对应的堆内存是log2对应堆内存的2倍 7.5g/3.5g
- 其他配置不变
很明显的可以发现,本项目在扩大堆内存的情况下,性能会所有提高,当然不是绝对的,有待测试
3.将log2和log3做对比:
- 二者均是采用CMS垃圾收集器
- lo2对应的非堆内存是log3对应堆内存的2倍 256/100
- 其他配置不变
很明显的发现,本项目扩大非堆内存的情况下,性能会有所提高,当然不是绝对的,有待测试
4.将log4和log6对比:
- 二者均是采用G1垃圾收集器
- log5对应的堆内存是log4对应的堆内存的2倍 7.5g/3.5g
- 其他配置不变
但是,我们发现,本项目采用G1垃圾收集器的情况下,扩大堆内存性能有所下降,当然不是绝对的,有待测试
5.将log5和log6做对比:
- 二者均是采用G1垃圾收集器
- log6对应的非堆内存是log5对应的非堆内存的2倍 256/100
- 其他配置不变
但是,我们发现,本项目采用G1垃圾收集器的情况下,扩大非堆内存性能有所下降,当然不是绝对的,有待测试
以上结果可以肯定的是,在开发环境下,本项目采用G1垃圾收集器比CMS垃圾收集器的性能要好,可以提高10%左右。