java服务器异常处理
java游戏服务端, 内存泄露怎么查看, 如果是线上的话怎么处理, 线上cpu 100%处理.
使用 jmap 手动 dump(最常用)
jmap -dump:live,format=b,file=heap.bin <pid>
live:只导出存活对象(强烈建议)
dump 文件一般很大(几个 G)
分析工具(重点)
MAT(Memory Analyzer Tool,首选)
jstat(看趋势)
jstat -gcutil <pid> 1000

1. 内存区域(单位:KB)
- S0:Survivor 0 区使用率
年轻代的两个幸存者区之一,存放存活的小对象
- S1:Survivor 1 区使用率
和 S0 交替使用,同一时间只有一个区有数据
- E:Eden 区使用率
新对象创建的地方,满了就触发年轻代 GC(YGC)
- O:Old 老年代使用率
存活时间长的对象、大对象存放区,满了触发FullGC(FGC)
- M:Metaspace 元空间使用率
存放类信息、方法、常量,JDK8 替代永久代
- CCS:Compressed Class Space 压缩类空间使用率
元空间的一部分,专门存放压缩后的类元数据
2. GC 次数 & 耗时(核心性能指标)
- YGC:Young GC 次数
年轻代垃圾回收的总次数
- YGCT:Young GC 总耗时(单位:秒)
所有年轻代 GC 加起来的总时间
- FGC:Full GC 次数
全堆垃圾回收(非常昂贵,越少越好)
- FGCT:Full GC 总耗时(秒)
所有 FullGC 的总时间
- GCT:GC 总耗时(秒)
YGCT + FGCT,所有 GC 的总耗时
快速判断 JVM 健康状态(实用口诀)
- FGC 多、FGCT 大 → 严重问题(内存泄漏、堆太小、大对象过多)
- O 区持续上涨不下降 → 大概率内存泄漏
- M 区满 → 类加载太多,需要调大元空间
关注:
O(Old 区)是否接近 100%
FGC 次数是否持续增长
jstack(看线程)
jstack <pid> > stack.txt
用于排查:
死循环
线程阻塞导致对象无法释放
jprofiler
线上可以使用
kill -15 来重启, 不是-9, -9为强杀, -15为优雅退出
保留日志
保留 gc.log
会触发 Full GC
大堆可能停顿数秒 ~ 数十秒
👉 非核心服 / 低峰期才做
开启 OOM 自动 dump
-XX:+HeapDumpOnOutOfMemoryError
jmap -histo(只统计数量,不 dump)
jmap -histo:live <pid>

cpu 100%
抓线程栈
jstack <pid> > jstack.txt
抓 3~5 次,间隔 5~10 秒
top -H -p <pid>
抓 CPU 占用最高的线程
top -H -p <pid>
你会看到类似:
tid 14023 99.9%
把 tid 转成 16 进制:
printf "%x\n" 14023
然后在 jstack.txt里搜:
nid=0x36f7
👉 直接定位到“罪魁祸首代码行”
1. top 确认 Java 进程
2. top -H -p <pid> 找最忙线程
3. jstack 抓栈(多次)
4. 转 tid 为 nid
5. 定位 RUNNABLE 代码
6. 看是否是循环 / 高频逻辑
7. 本地复现
8. 修复 + 压测
9. 灰度上线
top
top -H -p <pid>
jstack <pid> > jstack.txt 打印某个线程的堆
printf "%x\n" <tid>
grep -R "nid=0x<hex>" jstack.txt
jstat JVM Statistics Monitoring Tool, JDK 自带的、用来实时监控 Java 程序运行状态的命令行工具, 内存使用、垃圾回收(GC)、类加载, 用来查内存溢出.
jmap JVM Memory Map 查 JDK 自带的堆内存分析工具,专门用来导出内存快照、查看堆里有什么对象、排查内存泄漏. 看每种类型对象占用空间
jstack = JVM Stack Trace, 打印所有线程的调用栈, 定位死锁
- jstat:看内存、GC实时数据(动态监控)
- jmap:抓堆内存快照,查对象、OOM(内存问题)
- jstack:抓线程快照,查死锁、CPU 高、卡住(线程问题)
浙公网安备 33010602011771号