CentOS Java日志中GC日志解读方法
小樊
39
2025-12-07 17:46:24
CentOS 上 Java GC 日志解读方法
一 启用与收集 GC 日志
- 常用参数(适用于 JDK 8 及多数版本)
- 基础与滚动:
- -verbose:gc
- -XX:+PrintGCDetails(包含 PrintGC)
- -XX:+PrintGCTimeStamps(相对 JVM 启动的时间戳)
- -XX:+PrintGCDateStamps(日期时间格式)
- -Xloggc:/var/log/your-app/gc.log
- -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=20M
- 停顿与对象年龄:
- -XX:+PrintGCApplicationStoppedTime(打印 STW 停顿)
- -XX:+PrintTenuringDistribution(对象年龄分布)
- 示例(放在 JAVA_OPTS 或 systemd 的 ExecStart 中):
- -Xms4g -Xmx4g -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -Xloggc:/var/log/your-app/gc.log -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=20M -XX:+PrintGCApplicationStoppedTime -XX:+PrintTenuringDistribution
- Tomcat 场景
- 编辑 bin/catalina.sh,在 JAVA_OPTS 中追加上述参数,重启 Tomcat 后日志将输出到指定文件(如 /usr/local/tomcat/logs/tomcat_gc.log)。
- 注意
- 指定的日志目录必须存在,否则 JVM 不会输出 GC 日志。
- 滚动日志默认从 gc.log.0.current 开始写入,按大小滚动并循环覆盖,注意保留足够历史以便排查。
二 通用日志结构与字段含义
- 基本格式
- 时间戳前缀:如 33.125:(相对启动秒数)或 2014-02-28T11:59:00.638+0800: 766.537:(日期时间)
- 停顿类型:[GC] 或 [Full GC](Full 表示发生 STW 的全堆回收)
- 区域与堆变化:如 [PSYoungGen: 142816K->10752K(142848K)] 246648K->243136K(375296K), 0.0935090 secs
- 区域部分:回收前使用 -> 回收后使用(该区域容量)
- 堆部分:回收前堆使用 -> 回收后堆使用(堆总容量)
- 时间统计:[Times: user=0.55 sys=0.10, real=0.09 secs]
- user:GC 线程用户态 CPU 时间总和
- sys:GC 线程内核态 CPU 时间
- real:墙钟时间(应用实际停顿)
- 并行时常见关系:user + sys ≈ real × 并行线程数
- 区域名称与收集器
- DefNew(Serial 新生代)、ParNew(ParNew 新生代)、PSYoungGen(Parallel Scavenge 新生代)
- Tenured / ParOldGen(老年代)、Perm(永久代,JDK 7 及以前)、Metaspace(元空间,JDK 8+)
三 常见收集器日志要点
- Parallel Scavenge(常用在 JDK 8 默认)
- 典型:[GC (Allocation Failure) [PSYoungGen: 8192K->512K(9216K)] 8192K->6848K(19456K), 0.0034949 secs]
- 关注新生代回收效果与堆整体回收前后变化,评估吞吐量。
- CMS(并发标记清除)
- 阶段标识:CMS-initial-mark(STW)、CMS-concurrent-mark、CMS-concurrent-preclean、remark(STW)、concurrent-sweep
- 异常特征:并发阶段失败可能触发 Full GC(concurrent mode failure)。
- G1(Garbage First)
- 典型:[GC pause (G1 Evacuation Pause) (young), 0.0144227 secs]
- 关键区域行:[Eden: 24.0M(24.0M)->0.0B(20.0M) Survivors: 0.0B->4.0M Heap: 24.0M(256.0M)->20.4M(256.0M)]
- 关注 Humongous Allocation(大对象)、Mixed GC、以及各阶段耗时分布。
四 快速定位与优化思路
- 高频 Minor GC
- 特征:短时间内大量 [GC (Allocation Failure)],Eden 回收后迅速填满
- 思路:适当增大 新生代(-Xmn 或 -XX:NewRatio),降低对象分配速率,优化短命对象生命周期。
- 频繁 Full GC
- 特征:[Full GC (Metadata GC Threshold)] 或老年代空间不足导致
- 思路:检查 老年代 是否不足或存在泄漏;合理设置 -Xms/-Xmx;对 元空间 设置上限(如 -XX:MetaspaceSize=… -XX:MaxMetaspaceSize=…)避免频繁扩容触发 Full GC。
- 长时间停顿
- 特征:单次 real 超过业务容忍阈值(如 >500ms)
- 思路:G1 下关注 Humongous 分配与 Mixed GC 频率;CMS 下警惕并发失败;必要时切换或调优至 G1/ZGC 并设置目标停顿(如 -XX:MaxGCPauseMillis=200)。
- 过早晋升
- 特征:Tenuring Distribution 显示对象很快晋升到老年代
- 思路:增大 Survivor 区或 MaxTenuringThreshold,降低晋升速率。
五 常用分析命令与工具
- 命令行快速洞察
- 统计次数与时长:
- grep “GC” gc.log | wc -l
- grep “Full GC” gc.log | wc -l
- awk ‘/GC.*secs/ {sum+=$NF} END {print “Average GC time: " sum/NR " secs”}’ gc.log
- 观察晋升与堆趋势:
- grep -A 5 “Tenuring Distribution” gc.log
- 可视化与深度分析
- GCEasy(在线):上传 gc.log 生成停顿、频率、内存趋势报告
- GCViewer(本地):图形化查看 GC 频率、停顿分布、堆使用曲线
- Java Mission Control(JMC):导入 GC 日志与飞行记录器进行诊断。