1.JVM参数配置
-Xms64m -Xmx64m -Xss1m -XX:+UseG1GC -XX:MetaspaceSize=512m -XX:MaxMetaspaceSize=512m -XX:ParallelGCThreads=8 -XX:+HeapDumpOnOutOfMemoryError -Xloggc:/tmp/wse-gc-%t.log -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=20M -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCCause
2.参数说明
选项/默认值 | 说明 |
---|---|
-XX:+UseG1GC | 使用 G1 (Garbage First) 垃圾收集器 |
-XX:MaxGCPauseMillis=n | 设置最大GC停顿时间(GC pause time)指标(target). 这是一个软性指标(soft goal), JVM 会尽量去达成这个目标. |
-XX:InitiatingHeapOccupancyPercent=n | 启动并发GC周期时的堆内存占用百分比. G1之类的垃圾收集器用它来触发并发GC周期,基于整个堆的使用率,而不只是某一代内存的使用比. 值为 0 则表示"一直执行GC循环". 默认值为 45. |
-XX:NewRatio=n | 新生代与老生代(new/old generation)的大小比例(Ratio). 默认值为 2. |
-XX:SurvivorRatio=n | eden/survivor 空间大小的比例(Ratio). 默认值为 8. |
-XX:MaxTenuringThreshold=n | 提升年老代的最大临界值(tenuring threshold). 默认值为 15. |
-XX:ParallelGCThreads=n | 设置垃圾收集器在并行阶段使用的线程数,默认值随JVM运行的平台不同而不同. |
-XX:ConcGCThreads=n | 并发垃圾收集器使用的线程数量. 默认值随JVM运行的平台不同而不同. |
-XX:G1ReservePercent=n | 设置堆内存保留为假天花板的总量,以降低提升失败的可能性. 默认值是 10. |
-XX:G1HeapRegionSize=n | 使用G1时Java堆会被分为大小统一的的区(region)。此参数可以指定每个heap区的大小. 默认值将根据 heap size 算出最优解. 最小值为 1Mb, 最大值为 32Mb. |
3.G1日志详情
# Minor GC日志
2021-12-28T15:55:04.734+0800: 8.079: [GC pause (G1 Evacuation Pause) (young), 0.0292184 secs]
[Parallel Time: 17.5 ms, GC Workers: 8]
[GC Worker Start (ms): Min: 8079.3, Avg: 8079.5, Max: 8080.2, Diff: 0.9]
[Ext Root Scanning (ms): Min: 0.0, Avg: 0.8, Max: 4.2, Diff: 4.2, Sum: 6.5]
[Update RS (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.0]
[Processed Buffers: Min: 0, Avg: 0.0, Max: 0, Diff: 0, Sum: 0]
[Scan RS (ms): Min: 0.0, Avg: 0.0, Max: 0.1, Diff: 0.0, Sum: 0.2]
[Code Root Scanning (ms): Min: 0.0, Avg: 1.1, Max: 3.8, Diff: 3.8, Sum: 9.1]
[Object Copy (ms): Min: 12.9, Avg: 15.1, Max: 16.6, Diff: 3.7, Sum: 120.9]
[Termination (ms): Min: 0.0, Avg: 0.0, Max: 0.1, Diff: 0.1, Sum: 0.4]
[Termination Attempts: Min: 1, Avg: 156.9, Max: 212, Diff: 211, Sum: 1255]
[GC Worker Other (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.2]
[GC Worker Total (ms): Min: 16.4, Avg: 17.2, Max: 17.4, Diff: 0.9, Sum: 137.2]
[GC Worker End (ms): Min: 8096.7, Avg: 8096.7, Max: 8096.7, Diff: 0.0]
[Code Root Fixup: 0.2 ms]
[Code Root Purge: 0.0 ms]
[Clear CT: 0.5 ms]
[Other: 11.0 ms]
[Choose CSet: 0.0 ms]
[Ref Proc: 9.9 ms]
[Ref Enq: 0.1 ms]
[Redirty Cards: 0.5 ms]
[Humongous Register: 0.1 ms]
[Humongous Reclaim: 0.0 ms]
[Free CSet: 0.2 ms]
[Eden: 184.0M(184.0M)->0.0B(208.0M) Survivors: 20.0M->26.0M Heap: 202.8M(4096.0M)->26.0M(4096.0M)]
[Times: user=0.14 sys=0.00, real=0.03 secs]
# Full GC日志
2021-12-28T16:57:36.485+0800: 28.596: [Full GC (Allocation Failure) 62M->40M(64M), 0.5709655 secs]
[Eden: 0.0B(3072.0K)->0.0B(14.0M) Survivors: 0.0B->0.0B Heap: 62.9M(64.0M)->40.8M(64.0M)], [Metaspace: 61512K->61310K(1105920K)]
[Times: user=0.78 sys=0.11, real=0.57 secs]
解释1:
2021-12-28T15:55:04.734+0800: 8.079: [GC pause (G1 Evacuation Pause) (young), 0.0292184 secs]
这一句表示: 在2021-12-28T15:55:04.734+0800发生了GC, 发生时JVM运行了8.079s。这次是年轻代的垃圾回收,垃圾回收耗时0.0292184s。
解释2:
[Eden: 184.0M(184.0M)->0.0B(208.0M) Survivors: 20.0M->26.0M Heap: 202.8M(4096.0M)->26.0M(4096.0M)]
这一句说明了GC发生前后堆内存的变化。GC发生前,eden区使用184.0M,此时eden区的大小也是184.0M,可见eden区满了。GC发生后,eden区全部清空了(被复制到Servivors区了),同时eden区发生了扩容,变成了208.0M。Survivors区的内存使用从20.0M变成了26.0M,是因为eden去回收后还剩6M复制到了Servivors区。整改堆内存的使用从202.8M变成了26.0M,并且整个堆在GC前后没有发生扩容,内存还是4096.0M。
解释3:
[Times: user=0.14 sys=0.00, real=0.03 secs]
这一句说明了GC执行时用户态和内核态的时间使用,以及真实的时间使用。