温馨提示×

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-markCMS-concurrent-precleanremark(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 日志与飞行记录器进行诊断。

0