当前位置: 代码网 > it编程>编程语言>C/C++ > 解读GC日志中的各项指标用法

解读GC日志中的各项指标用法

2025年07月01日 C/C++ 我要评论
gc 日志是 jvm 性能调优的重要依据,不同垃圾收集器(如 cms、g1、zgc)的日志格式有所差异,但核心指标含义一致。以下是对 gc 日志中各项指标的详细解读:一、基础 gc 日志格式(以 g1

gc 日志是 jvm 性能调优的重要依据,不同垃圾收集器(如 cms、g1、zgc)的日志格式有所差异,但核心指标含义一致。

以下是对 gc 日志中各项指标的详细解读:

一、基础 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]

二、关键指标解析

1. gc 类型与触发原因

[gc pause (g1 evacuation pause) (young)
[full gc (metadata gc threshold)

gc 类型

  • gc:minor gc(新生代回收)
  • full gc:全堆回收(可能包含新生代、老年代、元空间)

触发原因

  • allocation failure:对象分配失败(eden 区空间不足)
  • metadata gc threshold:元空间达到阈值
  • g1 humongous allocation:大对象直接分配到老年代

2. 堆内存变化

[eden: 24.0m(24.0m)->0.0b(20.0m) survivors: 0.0b->4.0m heap: 24.0m(256.0m)->20.4m(256.0m)]

格式:区域名: 回收前使用量(总容量)->回收后使用量(新总容量)

关键指标

  • eden 区:gc 后通常被清空(0.0b)
  • survivor 区:对象在两个 survivor 区之间移动
  • heap:整个堆的使用情况(回收前 24.0m → 回收后 20.4m)

3. gc 耗时

0.0144227 secs

stw 时间:应用线程暂停的时间(本例中 14.4ms)

异常情况

  • 单次 gc 时间过长(如超过 500ms)
  • 频繁 gc 导致应用响应缓慢

4. 并行 / 并发阶段

[parallel time: 13.0 ms, gc workers: 8]
[concurrent marking (10.2 ms)]
  • parallel:多线程并行执行的阶段
  • concurrent:与应用线程并发执行的阶段(不产生 stw)
  • gc workers:并行 gc 线程数

5. 对象晋升与年龄分布

[tenuring distribution]
  age   1:    1310720 bytes,    1310720 total
  age   2:     655360 bytes,    1966080 total

age n:存活了 n 次 gc 的对象大小

异常情况

  • 大量对象在低年龄(如 age 1)就晋升到老年代
  • 晋升年龄分布不均匀(如 age 15 突然激增)

6. cpu 时间

[times: user=0.09 sys=0.00, real=0.01 secs]
  • user:所有 gc 线程在用户态消耗的 cpu 时间总和
  • sys:gc 线程在内核态消耗的 cpu 时间
  • real:实际流逝的时钟时间
  • 关系user + sys ≈ real × 并行线程数

7. 元空间 / 永久代

[metaspace: 2560k->2560k(1056768k)]
  • 元空间:存储类元数据(jdk 8+)
  • 永久代:类似元空间(jdk 7 及以前)
  • 异常情况:元空间持续增长,可能触发 full gc

三、不同收集器的日志差异

1. g1 收集器

[gc pause (g1 evacuation pause) (young), 0.0144227 secs]
[gc pause (g1 humongous allocation), 0.5123456 secs]

关键指标

  • humongous 对象分配(直接在老年代分配的大对象)
  • mixed gc(同时回收新生代和部分老年代)

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]

关键阶段

  • initial mark(初始标记,stw)
  • concurrent marking(并发标记)
  • remark(重新标记,stw)
  • concurrent sweep(并发清除)

3. parallel 收集器

[gc (allocation failure) [psyounggen: 8192k->512k(9216k)] 8192k->6848k(19456k), 0.0034949 secs]

特点

  • 仅包含并行阶段
  • 重点关注吞吐量(而非低延迟)

四、异常指标与问题定位

1. 频繁 full gc

日志特征

[full gc (metadata gc threshold) ... 0.5234120 secs]

可能原因

  • 老年代空间不足
  • 元空间持续增长
  • 内存泄漏

2. 长时间 stw

日志特征

[gc pause (g1 humongous allocation) ... 1.2345678 secs]

可能原因

  • 堆内存过大
  • cms 并发模式失败
  • 大量 humongous 对象

3. 过早晋升

日志特征

[tenuring distribution]
  age   1:  104857600 bytes, ...

可能原因

  • survivor 区空间不足
  • 对象分配率过高
  • -xx:maxtenuringthreshold设置过小

五、分析工具与实战建议

1. 命令行工具

# 统计gc次数
grep "gc" gc.log | wc -l

# 计算平均gc耗时
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 日志生成详细报告
  • gcviewer(本地):分析 gc 频率、内存趋势
  • java mission control:集成 gc 日志分析和飞行记录器

3. 关键分析步骤

  • 确认 gc 类型:区分 minor gc、major gc、full gc
  • 计算 gc 频率:每分钟 / 小时发生的 gc 次数
  • 分析内存趋势:堆内存使用量是否持续增长
  • 检查 gc 耗时:单次 gc 时间是否超过预期
  • 定位 gc 原因:allocation failure、metadata threshold 等

六、优化建议

1. 减少 full gc

# 增大元空间
java -xx:metaspacesize=256m -xx:maxmetaspacesize=512m yourapp

# 避免大对象直接进入老年代
java -xx:pretenuresizethreshold=1048576 yourapp

2. 降低 gc 耗时

# 使用g1收集器并限制最大停顿时间
java -xx:+useg1gc -xx:maxgcpausemillis=200 yourapp

# 增加并行gc线程数
java -xx:parallelgcthreads=16 yourapp

3. 优化对象晋升

# 增大survivor区比例
java -xx:survivorratio=6 yourapp

# 提高晋升年龄阈值
java -xx:maxtenuringthreshold=15 yourapp

通过深入理解 gc 日志中的各项指标,可以精准定位内存泄漏、对象分配不合理、收集器选择不当等问题,从而优化 jvm 配置,提升应用性能。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com