解讀GC日志中的各項(xiàng)指標(biāo)用法
GC 日志是 JVM 性能調(diào)優(yōu)的重要依據(jù),不同垃圾收集器(如 CMS、G1、ZGC)的日志格式有所差異,但核心指標(biāo)含義一致。
以下是對(duì) GC 日志中各項(xiàng)指標(biāo)的詳細(xì)解讀:
一、基礎(chǔ) GC 日志格式(以 G1 為例)
1. Minor GC 日志
[GC pause (G1 Evacuation Pause) (young), 0.0144227 secs] [Parallel Time: 13.0 ms, GC Workers: 8] [Eden: 24.0M(24.0M)->0.0B(20.0M) Survivors: 0.0B->4.0M Heap: 24.0M(256.0M)->20.4M(256.0M)] [Times: user=0.09 sys=0.00, real=0.01 secs]
2. Full GC 日志
[Full GC (Metadata GC Threshold) [PSYoungGen: 512K->0K(9216K)] [ParOldGen: 6336K->6848K(10240K)] 6848K->6848K(19456K), [Metaspace: 2560K->2560K(1056768K)], 0.0254310 secs] [Times: user=0.09 sys=0.00, real=0.03 secs]
二、關(guān)鍵指標(biāo)解析
1. GC 類型與觸發(fā)原因
[GC pause (G1 Evacuation Pause) (young) [Full GC (Metadata GC Threshold)
GC 類型:
GC
:Minor GC(新生代回收)Full GC
:全堆回收(可能包含新生代、老年代、元空間)
觸發(fā)原因:
Allocation Failure
:對(duì)象分配失?。‥den 區(qū)空間不足)Metadata GC Threshold
:元空間達(dá)到閾值G1 Humongous Allocation
:大對(duì)象直接分配到老年代
2. 堆內(nèi)存變化
[Eden: 24.0M(24.0M)->0.0B(20.0M) Survivors: 0.0B->4.0M Heap: 24.0M(256.0M)->20.4M(256.0M)]
格式:區(qū)域名: 回收前使用量(總?cè)萘?->回收后使用量(新總?cè)萘?
關(guān)鍵指標(biāo):
- Eden 區(qū):GC 后通常被清空(0.0B)
- Survivor 區(qū):對(duì)象在兩個(gè) Survivor 區(qū)之間移動(dòng)
- Heap:整個(gè)堆的使用情況(回收前 24.0M → 回收后 20.4M)
3. GC 耗時(shí)
0.0144227 secs
STW 時(shí)間:應(yīng)用線程暫停的時(shí)間(本例中 14.4ms)
異常情況:
- 單次 GC 時(shí)間過長(zhǎng)(如超過 500ms)
- 頻繁 GC 導(dǎo)致應(yīng)用響應(yīng)緩慢
4. 并行 / 并發(fā)階段
[Parallel Time: 13.0 ms, GC Workers: 8] [Concurrent Marking (10.2 ms)]
- Parallel:多線程并行執(zhí)行的階段
- Concurrent:與應(yīng)用線程并發(fā)執(zhí)行的階段(不產(chǎn)生 STW)
- GC Workers:并行 GC 線程數(shù)
5. 對(duì)象晉升與年齡分布
[Tenuring Distribution] age 1: 1310720 bytes, 1310720 total age 2: 655360 bytes, 1966080 total
age N:存活了 N 次 GC 的對(duì)象大小
異常情況:
- 大量對(duì)象在低年齡(如 age 1)就晉升到老年代
- 晉升年齡分布不均勻(如 age 15 突然激增)
6. CPU 時(shí)間
[Times: user=0.09 sys=0.00, real=0.01 secs]
- user:所有 GC 線程在用戶態(tài)消耗的 CPU 時(shí)間總和
- sys:GC 線程在內(nèi)核態(tài)消耗的 CPU 時(shí)間
- real:實(shí)際流逝的時(shí)鐘時(shí)間
- 關(guān)系:
user + sys ≈ real × 并行線程數(shù)
7. 元空間 / 永久代
[Metaspace: 2560K->2560K(1056768K)]
- 元空間:存儲(chǔ)類元數(shù)據(jù)(JDK 8+)
- 永久代:類似元空間(JDK 7 及以前)
- 異常情況:元空間持續(xù)增長(zhǎng),可能觸發(fā) Full GC
三、不同收集器的日志差異
1. G1 收集器
[GC pause (G1 Evacuation Pause) (young), 0.0144227 secs] [GC pause (G1 Humongous Allocation), 0.5123456 secs]
關(guān)鍵指標(biāo):
- Humongous 對(duì)象分配(直接在老年代分配的大對(duì)象)
- Mixed GC(同時(shí)回收新生代和部分老年代)
2. CMS 收集器
[GC (Allocation Failure) [ParNew: 61440K->61440K(61440K), 0.0000388 secs] [CMS: 0K->20480K(102400K), 0.0123456 secs] 61440K->20480K(163840K), [Metaspace: 2560K->2560K(1056768K)] 0.0123844 secs]
關(guān)鍵階段:
- Initial Mark(初始標(biāo)記,STW)
- Concurrent Marking(并發(fā)標(biāo)記)
- Remark(重新標(biāo)記,STW)
- Concurrent Sweep(并發(fā)清除)
3. Parallel 收集器
[GC (Allocation Failure) [PSYoungGen: 8192K->512K(9216K)] 8192K->6848K(19456K), 0.0034949 secs]
特點(diǎn):
- 僅包含并行階段
- 重點(diǎn)關(guān)注吞吐量(而非低延遲)
四、異常指標(biāo)與問題定位
1. 頻繁 Full GC
日志特征:
[Full GC (Metadata GC Threshold) ... 0.5234120 secs]
可能原因:
- 老年代空間不足
- 元空間持續(xù)增長(zhǎng)
- 內(nèi)存泄漏
2. 長(zhǎng)時(shí)間 STW
日志特征:
[GC pause (G1 Humongous Allocation) ... 1.2345678 secs]
可能原因:
- 堆內(nèi)存過大
- CMS 并發(fā)模式失敗
- 大量 Humongous 對(duì)象
3. 過早晉升
日志特征:
[Tenuring Distribution] age 1: 104857600 bytes, ...
可能原因:
- Survivor 區(qū)空間不足
- 對(duì)象分配率過高
-XX:MaxTenuringThreshold
設(shè)置過小
五、分析工具與實(shí)戰(zhàn)建議
1. 命令行工具
# 統(tǒng)計(jì)GC次數(shù) grep "GC" gc.log | wc -l # 計(jì)算平均GC耗時(shí) awk '/GC.*secs/ {sum+=$NF} END {print "Average GC time: " sum/NR " secs"}' gc.log # 提取堆使用情況 grep "\[Heap\]" gc.log | awk '{print $6, $8}' > heap_usage.txt
2. 可視化工具
- GCEasy(在線):上傳 GC 日志生成詳細(xì)報(bào)告
- GCViewer(本地):分析 GC 頻率、內(nèi)存趨勢(shì)
- Java Mission Control:集成 GC 日志分析和飛行記錄器
3. 關(guān)鍵分析步驟
- 確認(rèn) GC 類型:區(qū)分 Minor GC、Major GC、Full GC
- 計(jì)算 GC 頻率:每分鐘 / 小時(shí)發(fā)生的 GC 次數(shù)
- 分析內(nèi)存趨勢(shì):堆內(nèi)存使用量是否持續(xù)增長(zhǎng)
- 檢查 GC 耗時(shí):?jiǎn)未?GC 時(shí)間是否超過預(yù)期
- 定位 GC 原因:Allocation Failure、Metadata Threshold 等
六、優(yōu)化建議
1. 減少 Full GC
# 增大元空間 java -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=512m YourApp # 避免大對(duì)象直接進(jìn)入老年代 java -XX:PretenureSizeThreshold=1048576 YourApp
2. 降低 GC 耗時(shí)
# 使用G1收集器并限制最大停頓時(shí)間 java -XX:+UseG1GC -XX:MaxGCPauseMillis=200 YourApp # 增加并行GC線程數(shù) java -XX:ParallelGCThreads=16 YourApp
3. 優(yōu)化對(duì)象晉升
# 增大Survivor區(qū)比例 java -XX:SurvivorRatio=6 YourApp # 提高晉升年齡閾值 java -XX:MaxTenuringThreshold=15 YourApp
通過深入理解 GC 日志中的各項(xiàng)指標(biāo),可以精準(zhǔn)定位內(nèi)存泄漏、對(duì)象分配不合理、收集器選擇不當(dāng)?shù)葐栴},從而優(yōu)化 JVM 配置,提升應(yīng)用性能。
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
SpringBoot消息國(guó)際化配置實(shí)現(xiàn)過程解析
這篇文章主要介紹了SpringBoot消息國(guó)際化配置實(shí)現(xiàn)過程解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-07-07Java面試題之this 和 super 的區(qū)別解析
this 和 super 雖然都是Java中的關(guān)鍵字,但它們的作用和使用場(chǎng)景有著明顯的區(qū)別,下面給大家介紹Java面試題之this 和 super 的區(qū)別解析,感興趣的朋友一起看看吧2025-05-05Java基礎(chǔ)之邏輯運(yùn)算符知識(shí)總結(jié)
今天帶大家學(xué)習(xí)Java基礎(chǔ)知識(shí),文中對(duì)Java邏輯運(yùn)算符進(jìn)行了非常詳細(xì)的介紹,有相關(guān)代碼示例,對(duì)正在學(xué)習(xí)java的小伙伴很有幫助,需要的朋友可以參考下2021-05-05利用java和sqlserver建立簡(jiǎn)易圖書管理系統(tǒng)的完整步驟
圖書館管理系統(tǒng)是圖書館管理工作中不可缺少的部分,它對(duì)于圖書館的管理者和使用者都非常重要,下面這篇文章主要給大家介紹了關(guān)于利用java和sqlserver建立簡(jiǎn)易圖書管理系統(tǒng)的完整步驟,需要的朋友可以參考下2022-06-06MyBatis 二級(jí)緩存實(shí)現(xiàn)機(jī)制的示例解析
本文主要介紹了MyBatis 二級(jí)緩存實(shí)現(xiàn)機(jī)制的示例解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2025-05-05