gc参数调优
nohup java -jar -Xms4096m -Xmx4096m -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -XX:InitiatingHeapOccupancyPercent=40 -XX:G1HeapRegionSize=4 -XX:MaxTenuringThreshold=13 -XX:+UseStringDeduplication -XX:ConcGCThreads=2 -XX:AutoBoxCacheMax=20000 -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=256m -XX:+PrintGCApplicationStoppedTime -XX:+PrintPromotionFailure -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=$APP_HOME/java_pid${pid}.hprof -Xloggc:$APP_HOME/trade-gc.log -Duser.timezone=GMT+8 -verbose:gc -XX:+PrintGCDateStamps -XX:+PrintGCDetails ${JAR_FILE} >>/dev/null 2>&1 &
- -Xms:初始堆大小
- -Xmx:设置新生代大小
- -XX:+UseG1GC:使用G1垃圾回收器
- -XX:MaxGCPauseMillis:每次垃圾回收的最长时间,单位ms
- -XX:InitiatingHeapOccupancyPercent:如果整个堆的使用率超过这个值,G1会触发一次并发周期
- -XX:G1HeapRegionSize:使用G1时Java堆会被分为大小统一的的区(region)。此参数可以指定每个heap区的大小
- XX:MaxTenuringThreshold:控制新生代需要经历多少次GC晋升到老年代中的最大阈值
- -XX:+UseStringDeduplication:启用字符串重复数据删除
- -XX:ConcGCThreads:并发垃圾收集的线程数
- -XX:AutoBoxCacheMax:Integer缓存最大值
- -XX:MetaspaceSize:初始化的Metaspace的值大小,该值会触发gc
- -XX:MaxMetaspaceSize:Metaspace空间的最大值
- -XX:+PrintGCApplicationStoppedTime:显示垃圾回收期间程序暂停的时间
- -XX:+PrintPromotionFailure:显示是多大的新生代对象晋升到老生代失败从而引发Full GC 的
- -XX:+HeapDumpOnOutOfMemoryError:当JVM发生内存溢出时时,自动生成错误信息的DUMP文件
- -XX:HeapDumpPath:指定生成DUMP文件的路径以及文件名称
- Xloggc:gc日志文件的输出路径及文件名称
- -Duser.timezone:指定时区
- -verbose:打印jvm虚拟机中GC的详细情况
- -XX:+PrintGCDateStamps:打印gc的触发时间
- -XX:+PrintGCDetails:打印GC详细信息
2、gc日志分析
2020-06-19T10:47:33.199+0000: 15.533: [GC pause (G1 Evacuation Pause) (young) (to-space exhausted), 0.0189107 secs]
本次清理是在JVM启动1553.3ms 时开始的,清理的region区域是年轻代,即eden区域和survivor区域,暂停在JVM启动1553.3ms开始,完成这一次收集花费了0.0189107秒。
[Parallel Time: 14.5 ms, GC Workers: 4]
表明后面的活动由4个 Worker 线程并行执行, 消耗时间为14.5ms
[GC Worker Start (ms): Min: 15533.5, Avg: 15537.6, Max: 15539.4, Diff: 5.8]
GC的worker线程开始启动时,相对于 pause 开始的时间戳。如果 Min 和 Max 差别很大,则表明本机其他进程所使用的线程数量过多,挤占了GC的CPU时间。
[Ext Root Scanning (ms): Min: 0.0, Avg: 0.8, Max: 3.1, Diff: 3.1, Sum: 3.1]
用了多长时间来扫描堆外(non-heap)的root, 如 classloaders, JNI引用, JVM的系统root等。后面显示了运行时间, “Sum” 指的是CPU时间。
[Update RS (ms): Min: 3.7, Avg: 5.1, Max: 6.1, Diff: 2.5, Sum: 20.3]
[Processed Buffers: Min: 8, Avg: 14.2, Max: 27, Diff: 19, Sum: 57]
[Scan RS (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.0]
[Code Root Scanning (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.0]
用了多长时间来扫描实际代码中的 Root。
[Object Copy (ms): Min: 3.4, Avg: 4.4, Max: 5.1, Diff: 1.6, Sum: 17.6]
用了多长时间来拷贝收集区内的存活对象。
[Termination (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.0]
GC的worker线程用了多长时间来确保自身可以安全地停止, 这段时间什么也不用做, stop 之后该线程就终止运行了。
[Termination Attempts: Min: 1, Avg: 1.0, Max: 1, Diff: 0, Sum: 4]
[GC Worker Other (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.0]
一些琐碎的小活动,在GC日志中不值得单独列出来。
[GC Worker Total (ms): Min: 8.5, Avg: 10.3, Max: 14.3, Diff: 5.8, Sum: 41.0]
GC的worker 线程的工作时间总计。
[GC Worker End (ms): Min: 15547.8, Avg: 15547.8, Max: 15547.8, Diff: 0.0]
GC的worker 线程完成作业的时间戳,通常来说这部分数字应该大致相等,否则就说明有太多的线程被挂起
[Code Root Fixup: 0.0 ms]
释放用于管理并行活动的内部数据。一般都接近于零。这是串行执行的过程。
[Code Root Purge: 0.0 ms]
清理其他部分数据,也是非常快的, 但如非必要则几乎等于零。这是串行执行的过程。
[String Dedup Fixup: 0.9 ms, GC Workers: 4]
[Queue Fixup (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.0]
[Table Fixup (ms): Min: 0.8, Avg: 0.8, Max: 0.8, Diff: 0.0, Sum: 3.2]
[Clear CT: 0.2 ms]
[Other: 3.3 ms]
其他活动消耗的时间, 其中有很多是并行执行的。
[Evacuation Failure: 2.6 ms]
[Choose CSet: 0.0 ms]
[Ref Proc: 0.2 ms]
处理非强引用(non-strong)的时间: 进行清理或者决定是否需要清理。
[Ref Enq: 0.0 ms]
用来将剩下的 non-strong 引用排列到合适的 ReferenceQueue中。
[Redirty Cards: 0.1 ms]
[Humongous Register: 0.2 ms]
[Humongous Reclaim: 0.0 ms]
[Free CSet: 0.1 ms]
将回收集中被释放的小堆归还所消耗的时间, 以便他们能用来分配新的对象。
[Eden: 2048.0K(4096.0M)->0.0B(4096.0M) Survivors: 0.0B->0.0B Heap: 4096.0M(4096.0M)->4096.0M(4096.0M)]
Eden: 使用量(eden区总量)->回收后使用量(eden区总量) Survivors: 回收前使用量->回收后使用量 Heap: 回收前使用量(Heap总量)->回收后使用量(Heap总量),可以看出这个Heap 总量就是配置的量
[Times: user=0.04 sys=0.00, real=0.02 secs]
GC线程消耗的CPU总时间,系统调用和系统等待时间,应用暂停时间。