2021-03-25T13:00:41.631+0800: 4.013: [GC (Allocation Failure) [PSYoungGen: 419840K->20541K(472064K)] 419840K->20573K(996352K), 0.0118345 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]
详细内容如下:
Heap
PSYoungGen total 472064K, used 406352K [0x00000000e0000000, 0x0000000100000000, 0x0000000100000000)
eden space 419840K, 93% used [0x00000000e0000000,0x00000000f7f00528,0x00000000f9a00000)
from space 52224K, 27% used [0x00000000f9a00000,0x00000000fa7d3d70,0x00000000fcd00000)
to space 52224K, 0% used [0x00000000fcd00000,0x00000000fcd00000,0x0000000100000000)
ParOldGen total 524288K, used 189923K [0x00000000c0000000, 0x00000000e0000000, 0x00000000e0000000)
object space 524288K, 36% used [0x00000000c0000000,0x00000000cb978d08,0x00000000e0000000)
Metaspace used 111852K, capacity 117676K, committed 117888K, reserved 1153024K
class space used 13876K, capacity 14914K, committed 14976K, reserved 1048576K
详细内容如下:
12.097: [GC (Allocation Failure) 419840K->18067K(996352K), 0.0197196 secs]
30.677: [Full GC 243120K->241951K(629760K), 1.5589690 secs]
这个参数只是开启了简单的日志模式,为每一次新生代(Young Generation)的GC和每一次的Full GC 打印一行信息,
首先是GC类型(GC或者Full GC)然后是括号里是GC原因(Allocation Failure:分配对象空间不足导致新生代GC),然后是GC之前和GC之后已使用的堆空间,括号里是当前的堆容量,最后是本次GC的耗时时间(以秒计)。
第一行的意思就是新生代GC已使用的堆空间从419840K减少到18067K,当前的堆容量996352K,GC持续时间是0.0197196秒。
简单模式的GC日志格式是与GC算法无关的,日志没有提供太多的信息,也无法从日志里判定GC是否将一些对象从Young Generation移到了Old Generation。所以详细模式GC更有用些。
使用这个命令,就是开启了详细的GC日志模式。在这种模式下,日志格式和所使用的GC算法有关,
6.609: [GC (Allocation Failure) [PSYoungGen: 419840K->17473K(472064K)] 419840K->17561K(996352K), 0.0175394 secs] [Times: user=0.13 sys=0.00, real=0.02 secs]
12.399: [GC (Allocation Failure) [PSYoungGen: 437313K->32044K(472064K)] 437401K->32156K(996352K), 0.0302068 secs] [Times: user=0.11 sys=0.00, real=0.03 secs]
[Full GC
[PSYoungGen: 10752K->9707K(142848K)]
[ParOldGen: 232384K->232244K(485888K)] 243136K->241951K(628736K)
[PSPermGen: 3162K->3161K(21504K)], 1.5265450 secs
]
可以很容易发现,这是一次在Young Generation中的GC,它将新生代已使用的堆空间从419840K减少到17473K,新生代可用空间为472064K,GC前整个堆使用了419840K,GC后整个堆使用了17561K,整个堆的大小是996352K(新生代+老年代),耗时0.0175394秒,所使用的垃圾回收器是PS(Parallel Scavenge)。
Times包含了GC所使用的CPU时间信息(user+sys=0.13s时间之和),分别为操作系统的用户空间和系统空间所使用的时间,还有GC运行的真实时间(real=0.02 secs,0.02是近似值),如果CPU时间(0.13s)明显多于真实(real=0.02)时间,我们可以得出的结论:GC使用了多线程运行,这样的话CPU时间就是所有GC线程所花费的CPU时间的总和。
Full GC类似。Full GC也可以通过显示的请求而触发,可以是通过应用程序,或者是一个外部的JVM接口,这样触发的GC可以很容易在日志里分辨出来,因为输出的日志是以“Full GC(System)”开头的,而不是“Full GC”。
对于Serial垃圾收集器,详细的GC日志和Throughput垃圾收集器是非常相似的。唯一的区别是不同的generation日志可能使用了不同的GC算法(例如:old generation的日志可能以Tenured开头,而不是ParOldGen)。使用垃圾收集器作为一行日志的开头可以方便我们从日志就判断出JVM的GC设置。
对于CMS垃圾收集器,young generation的详细日志也和Throughput垃圾收集器非常相似,但是old generation的日志却不是这样。对于CMS垃圾收集器,在old generation中的GC是在不同的时间片内与应用程序同时运行的。GC日志自然也和Full GC的日志不同。而且在不同时间片的日志夹杂着在此期间young generation的GC日志。但是了解了上面介绍的GC日志的基本元素,也不难理解在不同时间片内的日志。只是在解释GC运行时间时要特别注意,由于大多数时间片内的GC都是和应用程序同时运行的,所以和那种独占式的GC相比,GC的持续时间更长一些并不说明一定有问题。
正如我们在第7节中所了解的,即使CMS垃圾收集器没有完成一个CMS周期,Full GC也可能会发生。如果发生了GC,在日志中会包含触发Full GC的原因,例如众所周知的”concurrent mode failure“(并发回收失败)。
使用-XX:PrintGCTimeStamps可以将实际和日期也加在GC日志中,表示JVM启动至今的时间戳会被添加到每一行中。
6.195: [GC (Allocation Failure) [PSYoungGen: 419840K->17894K(472064K)] 419840K->17982K(996352K), 0.0213569 secs] [Times: user=0.00 sys=0.03, real=0.02 secs]
如果指定了-XX:PrintGCDateStamps,每一行就添加上了绝对的日期和时间。
2021-03-31T13:58:47.268+0800: 6.963: [GC (Allocation Failure) [PSYoungGen: 419840K->16662K(472064K)] 419840K->16750K(996352K), 0.0325293 secs] [Times: user=0.08 sys=0.02, real=0.03 secs]
如果需要也可以同时使用两个参数。推荐同时使用这两个参数,因为这样在关联不同来源的GC日志时很有帮助。
缺省的GC日志输出到终端,-Xloggc:./gc.log指定输出到指定的文件,需要注意这个参数隐式的设置了参数-XX:+PrintGC和-XX:+PrintGCTimeStamps,但为了防止在新版本的JVM中有任何变化,建议显示的设置这些参数。
可管理的JVM参数,一个常常被讨论的问题就是生产环境中的GC日志是否应该开启,因为它所产生的开销通常都非常有限,因此我建议需要开启,但并不一定在启动JVM时就必须指定GC日志参数。
HotSpot JVM有一类特别的参数叫做可管理的参数,对于这些参数,可以在运行时修改它们的值,我们这里所讨论的所有参数以及以“PrintGC”开头的参数都是可管理的参数。这样在任何时候我们都可以开启或关闭GC日志,比如我们可以使用JDK自带的jinfo工具来设置这些参数,或者通过JMX客户端调用HotSpotDiagnostic MXBean的setVMOption方法来设置这些参数。例如:对PrintGC设置,参数1:PrintGC,参数2:true。打印日志即可设置成功。
2021-03-31T15:14:11.961+0800: 6.454: Application time: 0.1916132 seconds
2021-03-31T15:14:11.961+0800: 6.454: [GC (Allocation Failure) [PSYoungGen: 419840K->16530K(472064K)] 419840K->16618K(996352K), 0.0182229 secs] [Times: user=0.13 sys=0.00, real=0.02 secs]
打印每次垃圾回收前,程序未中断的执行时间。
2021-03-31T15:17:27.106+0800: 0.408: Application time: 0.0001266 seconds
2021-03-31T15:17:27.106+0800: 0.408: Total time for which application threads were stopped: 0.0000742 seconds, Stopping threads took: 0.0000398 seconds
打印垃圾回收期间程序暂停的时间,可以与上面的混合使用
打印GC前后的详细堆栈信息
{Heap before GC invocations=1 (full 0):
PSYoungGen total 472064K, used 419840K [0x00000000e0000000, 0x0000000100000000, 0x0000000100000000)
eden space 419840K, 100% used [0x00000000e0000000,0x00000000f9a00000,0x00000000f9a00000)
from space 52224K, 0% used [0x00000000fcd00000,0x00000000fcd00000,0x0000000100000000)
to space 52224K, 0% used [0x00000000f9a00000,0x00000000f9a00000,0x00000000fcd00000)
ParOldGen total 524288K, used 0K [0x00000000c0000000, 0x00000000e0000000, 0x00000000e0000000)
object space 524288K, 0% used [0x00000000c0000000,0x00000000c0000000,0x00000000e0000000)
Metaspace used 20878K, capacity 21480K, committed 21632K, reserved 1069056K
class space used 2766K, capacity 2937K, committed 2944K, reserved 1048576K
2021-03-31T15:23:07.849+0800: 8.961: [GC (Allocation Failure) [PSYoungGen: 419840K->14996K(472064K)] 419840K->15084K(996352K), 0.0182397 secs] [Times: user=0.00 sys=0.01, real=0.02 secs]
Heap after GC invocations=1 (full 0):
PSYoungGen total 472064K, used 14996K [0x00000000e0000000, 0x0000000100000000, 0x0000000100000000)
eden space 419840K, 0% used [0x00000000e0000000,0x00000000e0000000,0x00000000f9a00000)
from space 52224K, 28% used [0x00000000f9a00000,0x00000000fa8a5260,0x00000000fcd00000)
to space 52224K, 0% used [0x00000000fcd00000,0x00000000fcd00000,0x0000000100000000)
ParOldGen total 524288K, used 88K [0x00000000c0000000, 0x00000000e0000000, 0x00000000e0000000)
object space 524288K, 0% used [0x00000000c0000000,0x00000000c0016010,0x00000000e0000000)
Metaspace used 20878K, capacity 21480K, committed 21632K, reserved 1069056K
class space used 2766K, capacity 2937K, committed 2944K, reserved 1048576K
}
可以在启动参数中添加 -XX:+PrintFlagsFinal 参数,将会打印系统的所有参数,就可以看到自己配置的参数或系统的默认参数了,这个参数配置暂时用不到,只有在检查系统配置的时候才会使用,也可以通过JMX或者jdk自带的java Visual查看配置参数。这个是在系统启动参数里显示:
uintx MaxMetaspaceExpansion = 5451776 {product}
uintx MaxMetaspaceFreeRatio = 70 {product}
uintx MaxMetaspaceSize := 134217728 {product}
uintx MaxNewSize := 536870912 {product}
intx MaxNodeLimit = 75000 {C2 product}
uint64_t MaxRAM = 0 {pd product}
uintx MaxRAMFraction = 4 {product}
double MaxRAMPercentage = 25.000000 {product}
intx MaxRecursiveInlineLevel = 1 {product}
uintx MaxTenuringThreshold = 15 {product}
intx MaxTrivialSize = 6 {product}
intx MaxVectorSize = 32 {C2 product}
uintx MetaspaceSize := 134217728 {pd product}
打印GC日志参数配置:
只打印详细GC日志并输出到指定文件
-XX:+PrintGC
-XX:+PrintGCDetails
-XX:+PrintGCTimeStamps
-XX:+PrintGCDateStamps
-Xloggc:./gc.log
结果:
2021-03-31T15:31:05.603+0800: 6.487: [GC (Allocation Failure) [PSYoungGen: 419840K->16437K(472064K)] 419840K->16525K(996352K), 0.0220363 secs] [Times: user=0.02 sys=0.02, real=0.02 secs]
2021-03-31T15:31:11.544+0800: 12.428: [GC (Allocation Failure) [PSYoungGen: 436277K->31456K(472064K)] 436365K->31560K(996352K), 0.0307199 secs] [Times: user=0.06 sys=0.03, real=0.03 secs]
2021-03-31T15:31:19.701+0800: 20.585: [GC (Allocation Failure) [PSYoungGen: 451296K->38124K(472064K)] 451400K->38252K(996352K), 0.0416391 secs] [Times: user=0.09 sys=0.00, real=0.04 secs]
2021-03-31T15:31:27.432+0800: 28.315: [GC (Allocation Failure) [PSYoungGen: 457964K->48005K(472064K)] 458092K->48149K(996352K), 0.0587718 secs] [Times: user=0.24 sys=0.00, real=0.06 secs]
打印详细GC日志并输出到指定文件,并且打印每次GC前后的堆栈信息
-XX:+PrintGC
-XX:+PrintGCDetails
-XX:+PrintGCTimeStamps
-XX:+PrintGCDateStamps
-XX:+PrintHeapAtGC
-Xloggc:./gc.log
结果:
{Heap before GC invocations=1 (full 0):
PSYoungGen total 472064K, used 419840K [0x00000000e0000000, 0x0000000100000000, 0x0000000100000000)
eden space 419840K, 100% used [0x00000000e0000000,0x00000000f9a00000,0x00000000f9a00000)
from space 52224K, 0% used [0x00000000fcd00000,0x00000000fcd00000,0x0000000100000000)
to space 52224K, 0% used [0x00000000f9a00000,0x00000000f9a00000,0x00000000fcd00000)
ParOldGen total 524288K, used 0K [0x00000000c0000000, 0x00000000e0000000, 0x00000000e0000000)
object space 524288K, 0% used [0x00000000c0000000,0x00000000c0000018,0x00000000e0000000)
Metaspace used 22318K, capacity 22910K, committed 23168K, reserved 1069056K
class space used 2920K, capacity 3095K, committed 3200K, reserved 1048576K
2021-03-31T15:25:31.118+0800: 8.730: [GC (GCLocker Initiated GC) [PSYoungGen: 419840K->16575K(472064K)] 419840K->16663K(996352K), 0.0258389 secs] [Times: user=0.05 sys=0.00, real=0.03 secs]
Heap after GC invocations=1 (full 0):
PSYoungGen total 472064K, used 16575K [0x00000000e0000000, 0x0000000100000000, 0x0000000100000000)
eden space 419840K, 0% used [0x00000000e0000000,0x00000000e0000000,0x00000000f9a00000)
from space 52224K, 31% used [0x00000000f9a00000,0x00000000faa2fcb8,0x00000000fcd00000)
to space 52224K, 0% used [0x00000000fcd00000,0x00000000fcd00000,0x0000000100000000)
ParOldGen total 524288K, used 88K [0x00000000c0000000, 0x00000000e0000000, 0x00000000e0000000)
object space 524288K, 0% used [0x00000000c0000000,0x00000000c0016028,0x00000000e0000000)
Metaspace used 22318K, capacity 22910K, committed 23168K, reserved 1069056K
class space used 2920K, capacity 3095K, committed 3200K, reserved 1048576K
}
JVM参数在线检查