JVM 技術(shù)詳解:GC 日志解讀與分析(實(shí)例分析上篇)

在 JDK 9 之后的版本中,啟動參數(shù)有一些變化,繼續(xù)使用原來的參數(shù)配置可能會在啟動時報(bào)錯。不過也不用擔(dān)心,如果碰到,一般都可以從錯誤提示中找到對應(yīng)的處置措施和解決方案。

例如 JDK 11 版本中打印 info 級別 GC 日志的啟動腳本:

# JDK 11 環(huán)境,輸出 info 級別的 GC 日志
java -Xms512m -Xmx512m
-Xlog:gc*=info:file=gc.log:time:filecount=0
demo.jvm0204.GCLogAnalysis

從 JDK 9 開始,可以使用命令 java -Xlog:help 來查看當(dāng)前 JVM 支持的日志參數(shù),本文不進(jìn)行詳細(xì)的介紹,有興趣的同學(xué)可以查看 JEP 158: Unified JVM LoggingJEP 271: Unified GC Logging

另外,JMX 技術(shù)提供了 GC 事件的通知機(jī)制,監(jiān)聽 GC 事件的示例程序我們會在《應(yīng)對容器時代面臨的挑戰(zhàn)》這一章節(jié)中給出。

但很多情況下 JMX 通知事件中報(bào)告的 GC 數(shù)據(jù)并不完全,只是一個粗略的統(tǒng)計(jì)匯總。

GC 日志才是我們了解 JVM 和垃圾收集器最可靠和全面的信息,因?yàn)槔锩姘撕芏嗉?xì)節(jié)。再次強(qiáng)調(diào),分析 GC 日志是一項(xiàng)很有價值的技能,能幫助我們更好地排查性能問題。

下面我們通過實(shí)際操作來分析和解讀 GC 日志。

Serial GC 日志解讀

關(guān)于串行垃圾收集器的介紹,請參考前面的文章:《常見 GC 算法介紹》。

首先,為了打開 GC 日志記錄,我們使用下面的 JVM 啟動參數(shù)如下:

# 請注意命令行啟動時沒有換行,此處是手工排版
java -XX:+UseSerialGC
-Xms512m -Xmx512m
-Xloggc:gc.demo.log
-XX:+PrintGCDetails
-XX:+PrintGCDateStamps
demo.jvm0204.GCLogAnalysis

讓我們看看 Serial GC 的垃圾收集日志,并從中提取信息。

啟用串行垃圾收集器,程序執(zhí)行后輸出的 GC 日志類似這樣(為了方便大家閱讀,已手工折行):

Java HotSpot(TM) 64-Bit Server VM (25.162-b12) ......
Memory: 4k page,physical 16777216k(1551624k free)
CommandLine flags:
  -XX:InitialHeapSize=536870912 -XX:MaxHeapSize=536870912
  -XX:+PrintGC -XX:+PrintGCDateStamps
  -XX:+PrintGCDetails -XX:+PrintGCTimeStamps
  -XX:+UseCompressedClassPointers -XX:+UseCompressedOops
  -XX:+UseSerialGC
2019-12-15T15:18:36.592-0800: 0.420:
  [GC (Allocation Failure)
    2019-12-15T15:18:36.592-0800: 0.420:
    [DefNew: 139776K->17472K(157248K),0.0364555 secs]
    139776K->47032K(506816K),
    0.0365665 secs]
  [Times: user=0.02 sys=0.01,real=0.03 secs]
......
2019-12-15T15:18:37.081-0800: 0.908:
  [GC (Allocation Failure)
    2019-12-15T15:18:37.081-0800: 0.908:
    [DefNew: 156152K->156152K(157248K),0.0000331 secs]
    2019-12-15T15:18:37.081-0800: 0.908:
    [Tenured: 299394K->225431K(349568K),0.0539242 secs]
    455546K->225431K(506816K),
    [Metaspace: 3431K->3431K(1056768K)],
    0.0540948 secs]
  [Times: user=0.05 sys=0.00,real=0.05 secs]

日志的第一行是 JVM 版本信息,第二行往后到第一個時間戳之間的部分,展示了內(nèi)存分頁、物理內(nèi)存大小,命令行參數(shù)等信息,這部分前面介紹過,不在累述。

仔細(xì)觀察,我們發(fā)現(xiàn)在這段日志中發(fā)生了兩次 GC 事件,其中一次清理的是年輕代,另一次清理的是整個堆內(nèi)存。讓我們先來分析前一次年輕代 GC 事件。

Minor GC 日志分析

這次年輕代 GC 事件對應(yīng)的日志內(nèi)容:

2019-12-15T15:18:36.592-0800: 0.420:
  [GC (Allocation Failure)
    2019-12-15T15:18:36.592-0800: 0.420:
    [DefNew: 139776K->17472K(157248K),0.0364555 secs]
    139776K->47032K(506816K),
    0.0365665 secs]
  [Times: user=0.02 sys=0.01,real=0.03 secs]

從中可以解讀出這些信息:

還有 93% 的精彩內(nèi)容
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
支付 ¥19.99 繼續(xù)閱讀

友情鏈接更多精彩內(nèi)容