JVM调优参数大全、参数设置案例、日志分析

1.参数介绍

1.1 GC常用参数

1.1.1 常用数值型参数
  • -Xms 最小堆,为jvm启动时分配的内存,大点程序会启动的快一点。比如-Xms200m
  • -Xmx 最大堆,为jvm运行过程中分配的最大内存,比如-Xms500m
  • -Xmn 年轻代(初始和最大),整个堆大小=年轻代大小 + 年老代大小 + 持久代大小(方法区?)。持久代一般固定大小为64m,所以增大年轻代后,将会减小年老代大小。此值对系统性能影响较大,建议年轻代占堆大小的1/4 ~ 1/2[5]。Sun官方推荐配置为整个堆的3/8,如果设置太小,比如1/10会导致Minor GC 与Major GC次数增多。
  • -XX:AutoBoxCacheMax=20000 加大Integer Cache
  • -XX:MetaspaceSize=256m 元空间多次扩容后超过此值就会full gc 默认大约20M 元空间使用本地内存。 尽量设置足够,避免因为这个区域内存不够引发Full GC
  • -XX:MaxMetaspaceSize=256m 设置元空间最大大小 默认不限制 建议和MetaspaceSize一样大,一般256M
  • -XX:MaxTenuringThreshold 最大晋升年龄,最大值为15。The default value is 15 for the parallel collector and is 4 for CMS,G1中默认值为15。[0]

    存活对象开始存于eden,然后经历一个sur复制到另一个sur中,转移一次就加1代。达到指定代(满足该参数)的对象,转移到老年代。

1.1.2 打印日志(Debugging Options)
  • -verbose:gc 打印GC的简要信息,[GC 4790K->374K(15872K), 0.0001606 secs]。

    -XX:+PrintGC 打印GC的简要信息,[GC 4790K->374K(15872K), 0.0001606 secs],GC之前,用了4M左右的内存,GC之后,用了374K内存,一共回收了将近4M。内存大小一共是16M左右。和上个参数作用相同,选一个即可。
    -verbose:gc是一个标准的选项, -XX:+PrintGC是一个实验的选项,建议使用-verbose:gc替代-XX:+PrintGC[6]

  • -XX:+PrintGCDetails 打印GC详细信息,[GC[DefNew: 4416K->0K(4928K), 0.0001897 secs] 4790K->374K(15872K), 0.0002232 secs] [Times: user=0.33 sys=0.00, real=0.33 secs] ,这是一个新生代的GC。方括号内部的“4416K->0K(4928K)”含义是:“GC前该内存区域已使用容量->GC后该内存区域已使用容量(该内存区域总容量)”。而在方括号之外的“4790K->374K(15872K)”表示“GC前Java堆已使用容量->GC后Java堆已使用容量(Java堆总容量)”。 [Times: user=0.33 sys=0.00, real=0.33 secs]分别表示,用户态占用时长,内核用时,真实用时。

  • -XX:+PrintGCTimeStamps 输出GC的时间戳(以JVM启动到当期的总时长的时间戳形式)

  • -XX:+PrintGCDateStamps 输出GC的时间戳(以日期的形式,如 2013-05-04T21:53:59.234+0800)

  • -XX:+PrintHeapAtGC 每次gc(yonggc,fullgc) 都会输出gc前后堆详情(Eden区域、from区、to区、old区、Metaspace区 、Class space等)个人认为这个输出的gclog是目前最细的力度(极力推荐查找gc问题配置上这个参数)

  • -XX:+PrintPromotionFailure 知道是多大的新生代对象晋升到老生代失败从而引发Full GC时的。

示例参数1:
-verbose:gc -XX:+PrintGCDateStamps -XX:-PrintGCTimeStamps
打印日志:

2018-05-29T14:55:54.950+0530: [GC (Allocation Failure) 139776K->131335K(506816K), 0.2476636 secs]

示例参数2:
-verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps
打印日志:

2019一09一24T22:15:24.518+0800:3.287: [GC(Allocation Failure) [ PSYoungGen: 1361 62K一>5113K(136192K) ] 141425K一>17632K (222208K) ,0.0248249 secs] [Times: user=0.05sys=0.00, real=0.03 secs ]
2019一09一24T22:15:25.559+0800:4.329: [ GC(Metadata GC Threshold)[PSYoungGen:97578K一>10068K(274944K) ] 110096K一>22658K (360960K),0.0094071 secs]
[Times: user=0. 00sys=0.00, real=0. 01 secs]
2019一09一24T22:15:25.569+0800:4.338: [Full GC (Metadata GC Threshold)[ PSYoungGen:10068K一>0K(274944K) ] [ ParoldGen: 12590K一>13564K (56320K) ] 22658K一>13564K (331264K) ,
[Metaspace: 20590K一>20590K(1067008K)], 0. 0494875 secs]
[Times: user=0.17 sys=0. 02,real=0.05 secs ] 

示例参数3:
-verbose:gc -XX:+PrintHeapAtGC -Xmn64M -Xms256M -Xmx256M
打印日志:

{Heap before GC invocations=1 (full 0):
 PSYoungGen      total 57344K, used 49152K [0x00000000fc000000, 0x0000000100000000, 0x0000000100000000)
  eden space 49152K, 100% used [0x00000000fc000000,0x00000000ff000000,0x00000000ff000000)
  from space 8192K, 0% used [0x00000000ff800000,0x00000000ff800000,0x0000000100000000)
  to   space 8192K, 0% used [0x00000000ff000000,0x00000000ff000000,0x00000000ff800000)
 ParOldGen       total 196608K, used 0K [0x00000000f0000000, 0x00000000fc000000, 0x00000000fc000000)
  object space 196608K, 0% used [0x00000000f0000000,0x00000000f0000000,0x00000000fc000000)
 Metaspace       used 7901K, capacity 8264K, committed 8448K, reserved 1056768K
  class space    used 888K, capacity 986K, committed 1024K, reserved 1048576K
[GC (Allocation Failure)  49152K->2416K(253952K), 0.0030218 secs]
Heap after GC invocations=1 (full 0):
 PSYoungGen      total 57344K, used 2400K [0x00000000fc000000, 0x0000000100000000, 0x0000000100000000)
  eden space 49152K, 0% used [0x00000000fc000000,0x00000000fc000000,0x00000000ff000000)
  from space 8192K, 29% used [0x00000000ff000000,0x00000000ff258020,0x00000000ff800000)
  to   space 8192K, 0% used [0x00000000ff800000,0x00000000ff800000,0x0000000100000000)
 ParOldGen       total 196608K, used 16K [0x00000000f0000000, 0x00000000fc000000, 0x00000000fc000000)
  object space 196608K, 0% used [0x00000000f0000000,0x00000000f0004000,0x00000000fc000000)
 Metaspace       used 7901K, capacity 8264K, committed 8448K, reserved 1056768K
  class space    used 888K, capacity 986K, committed 1024K, reserved 1048576K
}

作者:青1475864380702
链接:https://juejin.cn/post/6844903791909666823
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

建议参数:(综上,如果想打印比较完整的日志信息,推荐如下参数)
-verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -XX:+PrintHeapAtGC

1.1.3 日志保存到文件
  • -Xloggc:<filename> 指定GClog的位置,以文件输出。帮助开发人员分析问题。设置该参数后,下方的参数有效。
  • -XX:+UseGCLogFileRotation: GC 日志超过阈值后滚动文件。必须与 -Xloggc:<filename> 一起使用
  • -XX:NumberOfGCLogFiles=<number of files>: 允许存储最多 n 个(must be >= 1) GC 日志文件。默认值为1。
  • -XX:GCLogFileSize=<number>M (or K): The size of the log file at which point the log will be rotated, must be >= 8K., 如 1m。默认值为512k

示例参数:
-Xloggc:/var/log/hbase/gc.log -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=100M

1.1.4 发生OOM时保存数据
  • -XX:+PerfDataSaveToFile # 在 pwdx ${pid} 目录, 生成 hsperfdata_pid 文件, 保存了 JVM 退出时的 jstat 各个状态值, 以便离线查看

    Linux中的pwdx命令,利用Java应用程序的进程号作为参数,可以打印出指定进程号的工作目录,帮助我们区分不同的进程。例如:pwd 32277,打印进程号为32277的进程工作目录,结果为该进程的工作目录。
    使用jstat如下显示包含在该文件中的性能数据:
    jstat -class file:/// / hsperfdata_
    jstat -gc file:/// / hsperfdata_

  • -XX:+HeapDumpOnOutOfMemoryError 当JVM发生OOM时,自动生成DUMP文件到${HeapDumpPath}。

    堆Dump是反应Java堆使用情况的内存镜像,其中主要包括系统信息、虚拟机属性、完整的线程Dump、所有类和对象的状态等。 一般,在内存不足、GC异常等情况下,我们就会怀疑有内存泄露。这个时候我们就可以制作堆Dump来查看具体情况。分析原因。

  • -XX:HeapDumpPath #生成DUMP文件的路径,也可以指定文件名称,例如:-XX:HeapDumpPath=${目录}/java_heapdump.hprof。如果不指定文件名,默认为:java_<pid>_<date>_<time>_heapDump.hprof

  • -XX:OnOutOfMemoryError="xxx.sh" 指定 OOM 发生时执行的脚本 (可以执行清理/告警/重启等操作)

1.2 GC其他参数

  • -Xss 栈空间,为jvm启动的每个线程分配的内存大小,默认JDK1.4中是256K,JDK1.5+中是1M
  • -XX:+DisableExplictGC 使System.gc()不管用。调用了System.gc()会进行FullGC。
  • -XX:+UseTLAB 使用TLAB,默认打开。线程本地分配缓存,这是一个线程独享的内存分配区域。TLAB解决了:直接在线程共享堆上安全分配带来的线程同步性能消耗问题(解决了指针碰撞)。TLAB内存空间位于Eden区。
  • -XX:TLABSize 设置TLAB大小
  • -XX:+PrintTLAB 打印TLAB的使用情况
  • -XX:+PrintGCApplicationConcurrentTime (低) 打印应用程序时间
  • -XX:+PrintGCApplicationStoppedTime (低) 打印暂停时长
  • -XX:+PrintReferenceGC (重要性低) 记录回收了多少种不同引用类型的引用
  • -verbose:class 类加载详细过程
  • -XX:+PrintVMOptions
  • -XX:+PrintFlagsFinal
  • -XX:+PrintFlagsInitial 必须会用
  • -XX:PreBlockSpin 热点代码检测参数
  • -XX:CompileThreshold 逃逸分析 标量替换 … 这些不建议设置

1.3 G1常用参数[0][7]

G1 GC 是自适应的垃圾回收器,提供了若干默认设置,使其无需修改即可高效地工作。以下是重要选项及其默认值的列表。此列表适用于最新的 Java HotSpot VM build 24。您可以通过在 JVM 命令行输入下列选项和已更改的设置,根据您的应用程序性能需求调整和调优 G1 GC。[7]
参考:https://www.oracle.com/java/technologies/javase/vmoptions-jsp.html

  • -XX:+UseG1GC 开启G1垃圾收集器

  • -XX:G1HeapRegionSize=16M 指定分区大小,16M?(1~32M,且必须是2的幂),目标是根据最小的 Java 堆大小划分出约 2048 个区域。建议逐渐增大该值,随着size增加,垃圾的存活时间更长,GC间隔更长,但每次GC的时间也会更长 ZGC做了改进(动态区块大小)

    如果没有明确指定,则自动根据Heap Size来指定,其对应关系如下:
    Min Heap Size Region Size
    heap < 4GB 1MB
    4GB <= heap < 8GB 2MB
    8GB <= heap < 16GB 4MB
    16GB <= heap < 32GB 8MB
    32GB <= heap < 64GB 16MB
    64GB <= heap 32MB

  • -XX:MaxGCPauseMillis=200 目标暂停时间(默认200ms),G1会尝试调整Young区的块数来达到这个值

  • -XX:InitiatingHeapOccupancyPercent 设置触发标记周期的 Java 堆占用率阈值。默认占用率是整个 Java 堆的 45%。

  • -XX:NewRatio=2 Ratio of old/new generation sizes. The default value is 2.

  • -XX:SurvivorRatio=8 Ratio of eden/survivor space size. The default value is 8.

  • -XX:MaxTenuringThreshold=n Maximum value for tenuring threshold. The default value is 15.

  • -XX:ParallelGCThreads=n 设置 STW 工作线程数的值。

    如果用户不指定:
    如果物理CPU所能够支持线程数小于8,默认为逻辑处理器的数量,阈值为8;
    如果物理CPU所能够支持线程数大于8,则ParallelGCThreads的值为8加上一个调整值,调整值的计算方式为:物理CPU所支持的线程数减去8所得值的5/8或者5/16,JVM会根据实际的情况来选择具体是乘以5/8还是5/16。比如,在64线程的x86 CPU上,如果用户未指定ParallelGCThreads的值,则默认的计算方式为:ParallelGCThreads = 8 + (64 - 8) * (5/8) = 8 + 35 = 43【5】

  • -XX:ConcGCThreads=n 设置并行标记的线程数。将 n 设置为并行垃圾回收线程数 (ParallelGCThreads) 的 1/4 左右。

  • -XX:G1NewSizePercent=5 新生代最小比例,默认为5%,JDK8u23已经移除 https://www.oracle.com/technical-resources/articles/java/g1gc.html)

  • -XX:G1MaxNewSizePercent=60 新生代最大比例,默认为60%,(JDK823已经移除 https://www.oracle.com/technical-resources/articles/java/g1gc.html)

  • -XX:+UseStringDeduplication 开启字符串去重 只适用于G1收集器(需要把你的Java升级到Java 8 update 20以及往后的版本。)

    背景:java应用内存里面的字符串占比大概是25%,有13.5%是重复的,字符串的平均长度是45。
    注意事项:有利有弊,详见:开启String去重XX:+UseStringDeduplication的利与弊https://blog.csdn.net/goldenfish1919/article/details/94555589

  • -XX:GCPauseIntervalMillis=0 响应时间优先,GC的停顿间隔时间,默认0。以指定最短多长可以进行一次gc。

  • -XX:GCTimeRatio=99 吞吐量优先,设置JVM吞吐量要达到的目标值,默认是 99。GC时间占用程序运行时间的百分比的差值。G1会根据这个值调整堆空间。也就应用程序线程应该运行至少99%的总执行时间,GC占 1%

2.调优参数详解(以G1 GC为例)

todo

3.参数设置案例及日志分析

doing

3.1 G1参数设置案例

3.1.1 案例1:8核 8G内存,使用G1 GC[5]
-XX:+UseG1GC
-XX:MaxGCPauseMillis=200
-XX:G1HeapRegionSize=4M 当使用G1收集器时,设置java堆被分割的region大小 1M~32M默认根据堆内存最优化设置
-XX:MaxTenuringThreshold=12  最大晋升年龄,从年轻代到老年代 Parallel Scavenge中默认值为15,CMS中默认值为6,G1中默认值为15
-XX:InitiatingHeapOccupancyPercent=40 堆占用达到多少开始并发垃圾回收 只有并发垃圾回收器生效。默认值45
-XX:ConcGCThreads=4 当前核心数的一半,并发GC线程数,也就是在STW阶段工作的GC线程数,值越大,吞吐量越小(应用的线程数减少)。默认是-XX:ParallelGCThreads/4。如果用户不指定,如果物理CPU所能够支持线程数小于8,阈值为8;如果物理CPU所能够支持线程数大于8,则ParallelGCThreads的值为8加上一个调整值,调整值的计算方式为:物理CPU所支持的线程数减去8所得值的5/8或者5/16,JVM会根据实际的情况来选择具体是乘以5/8还是5/16。比如,在64线程的x86 CPU上,如果用户未指定ParallelGCThreads的值,则默认的计算方式为:ParallelGCThreads = 8 + (64 - 8) * (5/8) = 8 + 35 = 43【5】
-XX:+UseStringDeduplication 开启字符串去重 G1回收器生效
-XX:AutoBoxCacheMax=20000 加大Integer Cache。默认是缓存-128 ~ +127 范围的数字
-XX:MetaspaceSize=128m 元空间多次扩容后超过此值就会full gc 默认大约20M 元空间使用本地内存。 尽量设置足够,避免因为这个区域内存不够引发Full GC
-XX:MaxMetaspaceSize=256m 设置元空间最大大小 默认不限制 建议和MetaspaceSize一样大,一般256M
-XX:+PrintPromotionFailure 知道是多大的新生代对象晋升到老生代失败从而引发Full GC时的。

-XX:+HeapDumpOnOutOfMemoryErro OOM时堆内存dump到当前目录
-XX:HeapDumpPath=${LOGDIR}/java_pid${pid}.hprof 设置堆内存dump的路径 

-Xloggc:${LOGDIR}/gc-myapp.log 将GC日志保存为文件
-verbose:gc -XX:+PrintGCDateStamps -XX:+PrintGCDetails  打印gc详细过程,打印GC日期,打印GC日志
-XX:+DisableExplicitGC 使System.gc()显式gc失效 默认不开启,
3.1.2 案例2 8核 6G内存,使用G1 GC

G1的调优目标主要是在避免FULL GC和疏散失败的前提下,尽量实现较短的停顿时间和较高的吞吐量。关于G1 GC的调优,需要记住以下几点:
不要自己显式设置新生代的大小(用Xmn或-XX:NewRatio参数),如果显式设置新生代的大小,会导致目标时间这个参数失效。[8]

-Xmx6000m 
-Xms6000m 
-XX:+UseG1GC #告诉JVM使用G1垃圾收集器
-XX:MaxTenuringThreshold=12 #最大晋升年龄,从年轻代到老年代 Parallel Scavenge中默认值为15,CMS中默认值为6,G1中默认值为15
-XX:MetaspaceSize=128m #元空间多次扩容后超过此值就会full gc 默认大约20M 元空间使用本地内存。 尽量设置足够,避免因为这个区域内存不够引发Full GC
-XX:MaxMetaspaceSize=128m #设置元空间最大大小 默认不限制 建议和MetaspaceSize一样大,一般256M

#打印日志
-verbose:gc 
-XX:+PrintGCDetails 
-XX:+PrintGCTimeStamps 
-XX:+PrintGCDateStamps 
-XX:+PrintHeapAtGC
-XX:+PrintPromotionFailure #知道是多大的新生代对象晋升到老生代失败从而引发Full GC时的。
#保存日志到文件
-Xloggc:/var/log/hbase/gc.log #日志保存到文件
-XX:+UseGCLogFileRotation #GC 日志超过阈值后滚动文件。必须与 `-Xloggc:<filename>` 一起使用
-XX:NumberOfGCLogFiles=5 #允许存储最多 n 个(must be >= 1) GC 日志文件。默认值为1。
-XX:GCLogFileSize=100M #<number>M (or K)。The size of the log file at which point the log will be rotated, must be >= 8K。默认值为512k。

#发生OOM时保存数据
-XX:+PerfDataSaveToFile # 在 pwdx ${pid} 目录, 生成 hsperfdata_pid 文件, 保存了 JVM 退出时的 jstat 各个状态值, 以便离线查看
-XX:+HeapDumpOnOutOfMemoryError #当JVM发生OOM时,自动生成DUMP文件到${HeapDumpPath}。
-XX:HeapDumpPath #生成DUMP文件的路径,也可以指定文件名称,例如:-XX:HeapDumpPath=${目录}/java_heapdump.hprof。如果不指定文件名,默认为:java_<pid>_<date>_<time>_heapDump.hprof。
-XX:OnOutOfMemoryError="xxx.sh" #指定 OOM 发生时执行的脚本 (可以执行清理/告警/重启等操作)

#G1一般都有默认值,且默认值的大小已经比较恰当。例如:
-XX:G1HeapRegionSize=2M 见上方参数介绍,会自动根据堆大小来变化,例如:4GB <= heap < 8GB	2MB
-XX:MaxGCPauseMillis=200,设置GC暂停时间的目标最大值,这是个柔性的目标,JVM会尽力达到这个目标
-XX:INitiatingHeapOccupancyPercent=45,如果整个堆的使用率超过这个值,G1会触发一次并发周期。记住这里针对的是整个堆空间的比例,而不是某个分代的比例。
等等......
设置参数:
export HADOOP_NAMENODE_OPTS="
-Xmx6000m -Xms6000m -XX:+UseG1GC -XX:MaxTenuringThreshold=12 -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=128m 
-verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -XX:+PrintHeapAtGC -XX:+PrintPromotionFailure 
-Xloggc:/....../logs/gc.log -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=50M 
-XX:+PerfDataSaveToFile -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/....../logs/ 
......"

对应日志分析:[9]

#新生代收集的标准流程,可以将它分成了几个步骤:
#GC之前的堆信息
#invocations 表示GC的次数,每次GC增加一次,每次GC前后的invocations相等
#{Heap before GC invocations=1 (full 0): 表示是第1次GC调用之后的堆内存状况
{Heap before GC invocations=176 (full 0):
 garbage-first heap   total 6144000K, used 3938959K [0x0000000649000000, 0x0000000649205dc0, 0x00000007c0000000)
  region size 2048K, 1800 young (3686400K), 7 survivors (14336K)
 Metaspace       used 62084K, capacity 63132K, committed 63360K, reserved 1105920K
  class space    used 6423K, capacity 6661K, committed 6784K, reserved 1048576K

#一、四个关键信息
#新生代垃圾收集发生的时间——2021-06-07T11:53:15.864+0800,通过设置-XX:+PrintGCDateStamps参数可以打印出这个时间;+0800表示是东8区。
#JVM启动后的相对时间——261607.934
#这次收集的类型——新生代收集,只回收Eden分区
#这次收集花费的时间——0.0342188 secs,即34ms
2021-06-07T11:53:15.864+0800: 261607.934: [GC pause (G1 Evacuation Pause) (young), 0.0342188 secs]

#二、列出了新生代收集中并行收集的详细过程
   #Parallel Time:并行收集任务在运行过程中引发的STW(Stop The World)时间,从新生代垃圾收集开始到最后一个任务结束,共花费18.3 ms
   #GC Workers:有23个线程负责垃圾收集,通过参数-XX:ParallelGCThreads设置,这个参数的值的设置,跟CPU有关,如果物理CPU支持的线程个数小于8,则最多设置为8;如果物理CPU支持的线程个数大于8,则默认值为number * 5/8
   [Parallel Time: 18.3 ms, GC Workers: 23]
      #GC Worker Start:第一个垃圾收集线程开始工作时JVM启动后经过的时间(min);最后一个垃圾收集线程开始工作时JVM启动后经过的时间(max);diff表示min和max之间的差值。理想情况下,你希望他们几乎是同时开始,即diff趋近于0。
      [GC Worker Start (ms): Min: 261607936.7, Avg: 261607937.2, Max: 261607937.9, Diff: 1.2]
      #Ext Root Scanning:扫描root集合(线程栈、JNI、全局变量、系统表等等)花费的时间,扫描root集合是垃圾收集的起点,尝试找到是否有root集合中的节点指向当前的收集集合(CSet)
      [Ext Root Scanning (ms): Min: 0.1, Avg: 1.0, Max: 3.8, Diff: 3.7, Sum: 22.1]
      #Update RS(Remembered Set or RSet):每个分区都有自己的RSet,用来记录其他分区指向当前分区的指针,如果RSet有更新,G1中会有一个post-write barrier管理跨分区的引用——新的被引用的card会被标记为dirty,并放入一个日志缓冲区,如果这个日志缓冲区满了会被加入到一个全局的缓冲区,在JVM运行的过程中还有线程在并发处理这个全局日志缓冲区的dirty card。Update RS表示允许垃圾收集线程处理本次垃圾收集开始前没有处理好的日志缓冲区,这可以确保当前分区的RSet是最新的。
      [Update RS (ms): Min: 1.1, Avg: 3.7, Max: 4.4, Diff: 3.3, Sum: 84.2]
         #Processed Buffers,这表示在Update RS这个过程中处理多少个日志缓冲区。
         [Processed Buffers: Min: 1, Avg: 7.2, Max: 21, Diff: 20, Sum: 165]
       #Scan RS:扫描每个新生代分区的RSet,找出有多少指向当前分区的引用来自CSet。
      [Scan RS (ms): Min: 0.2, Avg: 0.5, Max: 1.0, Diff: 0.8, Sum: 11.0]
      #Code Root Scanning:扫描代码中的root节点(局部变量)花费的时间
      [Code Root Scanning (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.1]
      #Object Copy:在疏散暂停期间,所有在CSet中的分区必须被转移疏散,Object Copy就负责将当前分区中存活的对象拷贝到新的分区。
      [Object Copy (ms): Min: 9.9, Avg: 10.4, Max: 11.0, Diff: 1.1, Sum: 239.3]
      #Termination:当一个垃圾收集线程完成任务时,它就会进入一个临界区,并尝试帮助其他垃圾线程完成任务(steal outstanding tasks),min表示该垃圾收集线程什么时候尝试terminatie,max表示该垃圾收集回收线程什么时候真正terminated。
      #Termination Attempts:如果一个垃圾收集线程成功盗取了其他线程的任务,那么它会再次盗取更多的任务或再次尝试terminate,每次重新terminate的时候,这个数值就会增加。
      [Termination (ms): Min: 1.3, Avg: 1.7, Max: 2.3, Diff: 1.0, Sum: 39.0]
      #GC Worker Other:垃圾收集线程在完成其他任务的时间
      [GC Worker Other (ms): Min: 0.0, Avg: 0.2, Max: 0.4, Diff: 0.4, Sum: 4.5]
      #GC Worker Total:展示每个垃圾收集线程的最小、最大、平均、差值和总共时间。
      [GC Worker Total (ms): Min: 16.6, Avg: 17.4, Max: 18.0, Diff: 1.4, Sum: 400.3]
      #GC Worker End:min表示最早结束的垃圾收集线程结束时该JVM启动后的时间;max表示最晚结束的垃圾收集线程结束时该JVM启动后的时间。理想情况下,你希望它们快速结束,并且最好是同一时间结束。
      [GC Worker End (ms): Min: 261607954.5, Avg: 261607954.6, Max: 261607954.8, Diff: 0.4]

#三、列出了新生代GC中的一些任务
   #Code Root Fixup :释放用于管理并行垃圾收集活动的数据结构,应该接近于0,该步骤是线性执行的;
   [Code Root Fixup: 0.1 ms]
   #Code Root Purge:清理更多的数据结构,应该很快,耗时接近于0,也是线性执行。
   [Code Root Purge: 0.0 ms]
   #Clear CT:清理card table
   [Clear CT: 1.2 ms]

#四、包含一些扩展功能
   [Other: 14.6 ms]
      #Choose CSet:选择要进行回收的分区放入CSet(G1选择的标准是垃圾最多的分区优先,也就是存活对象率最低的分区优先)
      [Choose CSet: 0.0 ms]
      #Ref Proc:处理Java中的各种引用——soft、weak、final、phantom、JNI等等。
      [Ref Proc: 7.6 ms]
      #Ref Enq:遍历所有的引用,将不能回收的放入pending列表
      [Ref Enq: 0.1 ms]
      #Redirty Card:在回收过程中被修改的card将会被重置为dirty
      [Redirty Cards: 1.0 ms]
      #Humongous Register:JDK8u60提供了一个特性,巨型对象可以在新生代收集的时候被回收——通过G1ReclaimDeadHumongousObjectsAtYoungGC设置,默认为true。
      #Humongous Reclaim:做下列任务的时间:确保巨型对象可以被回收、释放该巨型对象所占的分区,重置分区类型,并将分区还到free列表,并且更新空闲空间大小。
      [Humongous Reclaim: 0.0 ms]
      #Free CSet:将要释放的分区还回到free列表。
      [Free CSet: 3.3 ms]

#五、展示了不同代的大小变化,以及堆大小的自适应调整。
   #Eden: 3586.0M(3586.0M)->0.0B(3588.0M):(1)当前新生代收集触发的原因是Eden空间满了,分配了3586.0M;(2)所有的Eden分区都被疏散处理了,在新生代结束后Eden分区的使用大小成为了0.0B;(3)Eden分区的大小缩小为3586.0M
   #Survivors: 14.0M->12.0M:年轻代分区的回收处理之后,应该是有一部分晋升到新生者区了,survivor的空间从14.0M到12.0M;
   #Heap:3846.6M(6000.0M)->258.0M(6000.0M):(1)在本次垃圾收集活动开始的时候,堆空间整体使用量是3846.6M,堆空间的最大值是6000.0M;(2)在本次垃圾收集结束后,堆空间的使用量是258.0M,最大值保持不变。
   [Eden: 3586.0M(3586.0M)->0.0B(3588.0M) Survivors: 14.0M->12.0M Heap: 3846.6M(6000.0M)->258.0M(6000.0M)]
Heap after GC invocations=177 (full 0):
 garbage-first heap   total 6144000K, used 264152K [0x0000000649000000, 0x0000000649205dc0, 0x00000007c0000000)
  region size 2048K, 6 young (12288K), 6 survivors (12288K)
 Metaspace       used 62084K, capacity 63132K, committed 63360K, reserved 1105920K
  class space    used 6423K, capacity 6661K, committed 6784K, reserved 1048576K
}

#六、展示了本次新生代垃圾收集的时间
 #user=0.41:垃圾收集线程在新生代垃圾收集过程中消耗的CPU时间,这个时间跟垃圾收集线程的个数有关,可能会比real time大很多;分别表示用户态占用时长,内核用时,真实用时。
 [Times: user=0.41 sys=0.02, real=0.03 secs]

3.2 G1日志分析

【译】深入理解G1的GC日志(一)
https://juejin.cn/post/6844903893906751501

参考资料:

[0] 官网Java>Technical Details>Java SE>Java HotSpot VM
[1] GC和GC Tuning
[2] JVM性能调优实践——G1 垃圾收集器介绍篇
[3] 详解 JVM Garbage First(G1) 垃圾收集器
[4] JVM调优总结 -Xms -Xmx -Xmn -Xss
[5] JVM调优参数大全及G1GC调优
[6] Difference between -XX:+PrintGC and -verbose:gc
[7] 垃圾优先型垃圾回收器调优
[8] 可能是最全面的G1学习笔记
[9] 【译】深入理解G1的GC日志(一)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值