这篇文章将深入研究G1的日志和调优参数。为了在实际工作中对G1进行调优,作为开发者的你需要理解G1垃圾收集器的每个步骤,以及每个步骤在整个垃圾收集周期中的作用。为了方便读者学习,这篇文章将G1的日志参数分为等级递增的三块,这篇文章将会分别介绍每一部分参数的作用和调优时候使用的场景。
如果你要在生产环境中使用G1 GC,下面这些跟日志相关的参数是必备的,有了这些参数,你才能排查基本的垃圾回收问题。
配置参数 | 含义 |
---|---|
–Xloggc:/path/to/gc.log | gc日志文件的输出路径及文件名称 |
-XX:+UseGCLogFileRotation | 打开GC日志滚动记录功能,一般不建议设置 |
–XX:NumberOfGCLogFiles= | 设置要保留的GC日志文件个数 |
–XX:GCLogFileSize= | 设置合适的GC日志文件大小,单位:Kb |
–XX:+PrintGCDetails | 打印GC详细信息 |
–XX:+PrintGCDateStamps | 打印gc的触发时间 |
–XX:+PrintGCApplicationStoppedTime | 显示垃圾回收期间程序暂停的时间 |
–XX:+PrintGCApplicationConcurrentTime | 打印应用执行的时间 |
–XX:-PrintCommandLineFlags | 打印JVM设置过的详细的gc参数 |
使用==-XX:GCLogFileSize设置合适的GC日志文件大小,使用-XX:NumberOfGCLogFiles设置要保留的GC日志文件个数,使用-Xloggc:/path/to/gc.log==设置GC日志文件的位置,通过上面三个参数保留应用在运行过程中的GC日志信息,我建议最少保留一个星期的GC日志,这样应用的运行时信息足够多的,方便排查问题。
和其他垃圾收集器一样,G1也使用==-XX:PrintGCDetails==打印出详细的垃圾收集日志,下面这张图是新生代收集的标准流程,我在这里将它分成了6个步骤:
1、2020-06-22T08:20:27.622+0000: 6372.924: [GC pause (G1 Evacuation Pause) (young), 0.0905509 secs]
2、 [Parallel Time: 79.6 ms, GC Workers: 4]
[GC Worker Start (ms): Min: 6372924.2, Avg: 6372924.3, Max: 6372924.3, Diff: 0.1]
[Ext Root Scanning (ms): Min: 1.6, Avg: 3.5, Max: 8.1, Diff: 6.5, Sum: 14.0]
[Update RS (ms): Min: 0.0, Avg: 0.9, Max: 1.3, Diff: 1.3, Sum: 3.6]
[Processed Buffers: Min: 0, Avg: 6.0, Max: 14, Diff: 14, Sum: 24]
[Scan RS (ms): Min: 1.3, Avg: 1.5, Max: 2.0, Diff: 0.7, Sum: 6.1]
[Code Root Scanning (ms): Min: 3.5, Avg: 4.4, Max: 6.2, Diff: 2.7, Sum: 17.8]
[Object Copy (ms): Min: 66.4, Avg: 69.0, Max: 71.0, Diff: 4.6, Sum: 275.9]
[Termination (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.0]
[Termination Attempts: Min: 1, Avg: 1.0, Max: 1, Diff: 0, Sum: 4]
[GC Worker Other (ms): Min: 0.0, Avg: 0.1, Max: 0.1, Diff: 0.1, Sum: 0.4]
[GC Worker Total (ms): Min: 79.3, Avg: 79.4, Max: 79.5, Diff: 0.2, Sum: 317.6]
[GC Worker End (ms): Min: 6373003.6, Avg: 6373003.7, Max: 6373003.7, Diff: 0.1]
3、[Code Root Fixup: 0.4 ms]
[Code Root Purge: 0.3 ms]
[String Dedup Fixup: 3.2 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: 2.8, Avg: 3.0, Max: 3.1, Diff: 0.3, Sum: 11.9]
[Clear CT: 0.8 ms]
4、[Other: 6.3 ms]
[Choose CSet: 0.0 ms]
[Ref Proc: 3.4 ms]
[Ref Enq: 0.0 ms]
[Redirty Cards: 0.1 ms]
[Humongous Register: 0.2 ms]
[Humongous Reclaim: 0.0 ms]
[Free CSet: 2.2 ms]
5、 [Eden: 2337.0M(2337.0M)->0.0B(2389.0M) Survivors: 120.0M->68.0M Heap: 2463.0M(4096.0M)->81.8M(4096.0M)]
6、[Times: user=0.34 sys=0.00, real=0.09 secs]
G1的第二种收集活动是并发垃圾收集,并发垃圾收集的触发条件有很多,但是做的工作都相同,它的日志如下所示:
1、2020-06-19T12:02:00.008+0000: 4482.342: [GC pause (G1 Evacuation Pause) (young) (initial-mark) (to-space exhausted), 0.1400888 secs]
2、 2020-06-19T12:02:00.148+0000: 4482.482: [GC concurrent-root-region-scan-start]
2020-06-19T12:02:00.148+0000: 4482.482: [GC concurrent-root-region-scan-end, 0.0000847 secs]
3、 2020-06-19T12:02:00.148+0000: 4482.482: [GC concurrent-mark-start]
2020-06-19T12:02:00.279+0000: 4482.613: [GC concurrent-mark-end, 0.1311217 secs]
4、 2020-06-19T12:02:00.280+0000: 4482.614: [GC remark
2020-06-19T12:02:00.280+0000: 4482.614: [Finalize Marking, 0.0002808 secs]
2020-06-19T12:02:00.280+0000: 4482.614: [GC ref-proc, 0.0196855 secs]
2020-06-19T12:02:00.300+0000: 4482.634: [Unloading, 0.0296982 secs], 0.0531480 secs]
[Times: user=0.14 sys=0.01, real=0.05 secs]
5、 2020-06-19T23:20:00.589+0000: 45162.923: [GC cleanup 2758M->2628M(4096M), 0.0045787 secs]
[Times: user=0.02 sys=0.00, real=0.00 secs]
6、 2020-06-19T23:20:00.593+0000: 45162.928: [GC concurrent-cleanup-start]
2020-06-19T23:20:00.594+0000: 45162.928: [GC concurrent-cleanup-end, 0.0002474 secs]
GC concurrent-root-region-scan-start: 根分区扫描开始,根分区扫描主要扫描的是新的survivor分区,找到这些分区内的对象指向当前分区的引用,如果发现有引用,则做个记录;
GC concurrent-root-region-scan-end: 根分区扫描结束,耗时0.0030613s
Finalize Marking: Finalizer列表里的Finalizer对象处理,耗时0.0014099s;
GC concurrent-cleanup-start: 并发清理阶段启动。完成第5步剩余的清理工作;将完全清理好的分区加入到二级free列表,等待最终还会到总体的free列表;
GC concurrent-cleanup-end: 并发清理阶段结束,耗时0.0012954s
在并发收集阶段结束后,你会看到混合收集阶段的日志,如下图所示,该日志的大部分跟之前讨论的新生代收集相同,只有第1部分不一样:GC pause (G1 Evacuation Pause) (mixed) (to-space exhausted), 0.0641103 secs,这一行表示这是一个混合垃圾收集周期;在混合垃圾收集处理的CSet不仅包括新生代的分区,还包括老年代分区——也就是并发标记阶段标记出来的那些老年代分区。
1、2020-06-19T12:36:00.123+0000: 6522.458: [GC pause (G1 Evacuation Pause) (mixed) (to-space exhausted), 0.0641103 secs]
2、 [Parallel Time: 12.6 ms, GC Workers: 4]
[GC Worker Start (ms): Min: 6522458.3, Avg: 6522458.4, Max: 6522458.4, Diff: 0.1]
[Ext Root Scanning (ms): Min: 1.6, Avg: 1.8, Max: 2.2, Diff: 0.7, Sum: 7.2]
[Update RS (ms): Min: 1.6, Avg: 2.4, Max: 2.8, Diff: 1.1, Sum: 9.5]
[Processed Buffers: Min: 15, Avg: 21.5, Max: 27, Diff: 12, Sum: 86]
[Scan RS (ms): Min: 0.4, Avg: 0.5, Max: 0.5, Diff: 0.2, Sum: 1.9]
[Code Root Scanning (ms): Min: 0.0, Avg: 0.1, Max: 0.2, Diff: 0.2, Sum: 0.2]
[Object Copy (ms): Min: 7.2, Avg: 7.8, Max: 8.4, Diff: 1.2, Sum: 31.1]
[Termination (ms): Min: 0.0, Avg: 0.0, Max: 0.1, Diff: 0.1, Sum: 0.1]
[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 Worker Total (ms): Min: 12.5, Avg: 12.5, Max: 12.5, Diff: 0.0, Sum: 50.1]
[GC Worker End (ms): Min: 6522470.9, Avg: 6522470.9, Max: 6522470.9, Diff: 0.0]
3、[Code Root Fixup: 0.0 ms]
[Code Root Purge: 0.0 ms]
[String Dedup Fixup: 1.6 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.0, Avg: 1.1, Max: 1.5, Diff: 1.5, Sum: 4.3]
[Clear CT: 0.2 ms]
4、[Other: 49.6 ms]
[Evacuation Failure: 48.3 ms]
[Choose CSet: 0.3 ms]
[Ref Proc: 0.2 ms]
[Ref Enq: 0.0 ms]
[Redirty Cards: 0.1 ms]
[Humongous Register: 0.2 ms]
[Humongous Reclaim: 0.0 ms]
[Free CSet: 0.3 ms]
5、 [Eden: 157.0M(4096.0M)->0.0B(4096.0M) Survivors: 0.0B->0.0B Heap: 4093.4M(4096.0M)->4023.4M(4096.0M)]
6、[Times: user=0.21 sys=0.00, real=0.07 secs]
如果堆内存空间不足以分配新的对象,或者是Metasapce空间使用率达到了设定的阈值,那么就会触发Full GC——你在使用G1的时候应该尽量避免这种情况发生,因为G1的Full Gc是单线程、会Stop The World,代价非常高。Full GC的日志如下图所示,从中你可以看出三类信息
1、2020-06-19T10:47:33.227+0000: 15.561: [Full GC (Allocation Failure) 4096M->96M(4096M), 0.3302938 secs]
[Eden: 0.0B(4096.0M)->0.0B(4096.0M) Survivors: 0.0B->0.0B Heap: 4096.0M(4096.0M)->96.0M(4096.0M)], [Metaspace: 40813K->40629K(1085440K)]
[Times: user=0.38 sys=0.03, real=0.33 secs]
基础配置参数中,我这里还想介绍两个:-XX:+PrintGCApplicationStoppedTime和==-XX:+PrintGCApplicationConcurrentTime==,这两个参数也可以为你提供有用的信息,如下图所示:
2020-06-22T06:34:20.256+0000: 5.558:
1、Total time for which application threads were stopped: 0.0001350 seconds
2、Stopping threads took: 0.0000373 seconds