当前位置: 代码网 > it编程>编程语言>Java > Java故障排查之GC日志、线程堆栈、内存快照dump全套命令总结

Java故障排查之GC日志、线程堆栈、内存快照dump全套命令总结

2026年09月09日 Java 我要评论
环境准备与基础信息环境要求:linux 系统,jdk8 或 jdk11+。第一步:获取 java 进程 pid# 方法一:使用 jpsjps -l方法二:使用 psps -ef | grep java

环境准备与基础信息

环境要求:linux 系统,jdk8 或 jdk11+。

第一步:获取 java 进程 pid

# 方法一:使用 jps
jps -l
方法二:使用 ps
ps -ef | grep java

假设获取到的进程 pid 为 12345,下文所有命令中的 pid 请替换为你的实际进程 id。

一、线程堆栈 threaddump(现场抓取,建议多次抓取对比)

threaddump 用于排查死锁、线程阻塞、cpu 飙高等问题。

方式 1:jstack(最常用)

# 输出线程栈到文件
jstack 12345 > thread_dump_12345_$(date +%y%m%d_%h%m).txt
连续抓取 3 次,间隔 2 秒(便于观察线程状态变化)
jstack 12345 > thread1.txt
sleep 2
jstack 12345 > thread2.txt
sleep 2
jstack 12345 > thread3.txt
强制模式(当进程无响应时使用)
jstack -f 12345 > thread_dump_force.txt

方式 2:kill -3(不杀死进程,仅输出线程栈)

kill -3 12345

⚠️ 注意:这是 kill -3,不是 kill -9kill -3 只是向进程发送信号,用于打印线程栈到标准输出(通常为 catalina.out 或应用日志)。

二、内存快照 heapdump(.hprof 文件,排查 oom、内存泄漏)

1. jmap 手动触发 dump(进程存活时抓取)

# 完整堆 dump,live=true 只 dump 存活对象(推荐,过滤死亡对象,文件更小)
jmap -dump:live,format=b,file=heap_12345_$(date +%y%m%d_%h%m).hprof 12345

参数说明:

  • live:执行 fullgc,只保存存活对象,文件更小;去掉 live 会 dump 全部对象(包括垃圾对象)。
  • format=b:二进制 hprof 格式,mat 等工具可识别。
# 强制模式(当进程无响应时使用)
jmap -dump:live,format=b,file=heap_force.hprof -f 12345

2. oom 自动 dump(需事前配置,故障发生后无法临时添加)

在 jvm 启动参数中添加以下配置,发生 oom 时自动生成 hprof 文件:

-xx:+heapdumponoutofmemoryerror
-xx:heapdumppath=/data/logs/heapdump.hprof

两种 oom 情况:

  1. jvm 内部 oom:java 抛出 java.lang.outofmemoryerror,进程可能退出,也可能僵死不退出(假死,不响应请求,cpu 使用率低)。
  2. 系统层 oom killer:整机物理内存耗尽,操作系统直接杀死 java 进程,dmesg 中可见 oom-kill 记录。

业务恢复手段:

  • 进程僵死(进程存在但接口无响应、页面卡死):先抓现场,再重启进程,切勿直接 kill。
  • 进程已被系统 oom killer 杀死:直接启动应用,恢复业务。
  • 多实例部署:若集群有多台机器,可先下线故障节点,由其他机器承接流量,保证业务可用性,再排查故障机器。

三、gc 日志(重点:gc 日志不能事后抓取!必须 jvm 启动时预先开启)

jdk8 gc 日志启动参数

-xx:+printgcdetails
-xx:+printgcdatestamps
-xx:+printgctimestamps
-xloggc:/data/logs/gc-%t.log
-xx:+usegclogfilerotation
-xx:numberofgclogfiles=10
-xx:gclogfilesize=100m

jdk11+ 使用统一 xlog(新 api)

-xlog:gc*:file=/data/logs/gc-%t.log:time,uptimemillis:filecount=10,filesize=100m

故障现场实时查看 gc 状态(jstat,实时采样)

# 每 1000ms 输出一次,共输出 20 次
jstat -gc 12345 1000 20

重点监控指标:ygc(young gc 次数)、ygct(young gc 时间)、fgc(full gc 次数)、fgct(full gc 时间)、gct(总 gc 时间)。关注 fullgc 次数和总停顿时间。

查看 gc 日志:

  • 若 jvm 启动参数已配置 gc 日志,直接查看日志文件,关注频繁 fullgc、oom 异常;
  • 若未开启历史 gc 日志,可现场实时采样 gc 状态:
jstat -gc pid 1000 30 > jstat_gc.log

查看应用 stdout/catalina.out 日志:

# 搜索 oom 异常堆栈
grep -n "outofmemoryerror" app.log

若进程已被杀死、不复存在:无法通过 jstack / jmap 抓取 dump,只能依赖历史监控、gc 日志、应用日志进行复盘。

四、故障现场完整操作脚本(可直接复制执行)

pid=12345
date=$(date +%y%m%d_%h%m%s)
1. 连续 3 次线程 dump
jstack $pid > thread_dump_${date}1.txt
sleep 2
jstack $pid > thread_dump${date}2.txt
sleep 2
jstack $pid > thread_dump${date}_3.txt
2. 堆内存快照(注意:大堆 dump 会卡顿业务!确保磁盘空间充足)
jmap -dump:live,format=b,file=heapdump_${date}.hprof $pid
3. 实时 gc 采样
jstat -gc $pid 1000 10 > jstat_gc_${date}.log

五、工具总结清单

内容命令输出文件用途备注
线程堆栈jstack pid > xxx.txt.txt死锁、cpu 高、线程阻塞抓 3 次对比;卡死用 -f
堆内存快照jmap -dump:live,format=b,file=xxx.hprof pid.hprof内存泄漏、oom 分析大堆会 stw,占磁盘 io
gc 历史日志jvm 启动参数 -xloggcgc-xxx.loggc 停顿、频繁 fullgc必须提前开启,事后无法抓取
实时 gc 状态jstat -gc pid 1000 20控制台输出现场看当前 gc 情况快照采样,不是历史日志
线程栈备选kill -3 pid输出到应用 stdout/catalina.out线程栈不会杀死进程

六、常见注意事项

  • jmap dump 大堆(>8g)会造成业务卡顿,尽量在业务低峰期执行;故障迫不得已时才执行。
  • gc 日志必须 jvm 启动时配置,进程已经挂了就拿不到 gc 历史。
  • hprof 文件需要 mat 工具解析,不要直接使用 vim 打开。
  • 执行 jstack/jmap 需要和 java 进程同用户,root 用户有时会因权限问题导致异常。

总结 

到此这篇关于java故障排查之gc日志、线程堆栈、内存快照dump全套命令总结的文章就介绍到这了,更多相关java故障排查命令内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

相关文章:

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

发表评论

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