外观
03 · Java 专题
Java 应用在 Linux 上的问题,八成是JVM 参数、GC 行为、线程状态这三件事没看懂。这一章给的是定位路径,不是八股。
小节规划
| 小节 | 内容 | 状态 |
|---|---|---|
| JDK 安装与多版本切换 | tar 包安装、alternatives、JAVA_HOME 生效顺序 | 已写 |
| 启动参数速查 | 堆/元空间/GC 选择/线程栈/直接内存,容器内该配什么 | 已写 |
| JDK 命令行工具 | jps / jstat / jmap / jstack / jcmd / jinfo 各自适用场景 | 已写 |
| Arthas 实战 | dashboard、thread -b、watch、trace、热更新 | 已写 |
| GC 日志解读 | 各版本日志格式、Full GC 触发原因、晋升失败 | 已写 |
| CPU 100% 定位 | top -H 拿线程号转 16 进制对 jstack | 已写 |
| OOM 与堆转储 | 各类 OOM 的区分、jmap 抓 dump 与 MAT 分析 | 已写 |
| 服务托管 | jar 的 systemd unit、优雅停机、PID 与信号处理 | 已写 |
| Maven 与私服 | settings.xml、镜像、依赖冲突排查 | 已写 |
| 容器里的 Java | cgroup 感知、内存 limit 与堆大小、优雅关闭 | 已写 |
一条命令抓现场
线上出问题又不敢重启时,先把这套快照留住:
bash
PID=$(jps -l | grep your-app.jar | awk '{print $1}')
jcmd $PID VM.flags # 当前生效参数
jstat -gcutil $PID 1000 10 # 10 秒 GC 趋势
jstack -l $PID > /tmp/stack.$(date +%s).txt # 线程栈,连抓 3 次
jmap -histo:live $PID | head -30 # 存活对象直方图(会触发一次 Full GC,谨慎)
jcmd $PID GC.heap_dump /tmp/heap.hprof # 完整堆转储
dmesg -T | grep -i -E 'oom|killed process' | tail # 有没有被内核杀jmap -dump 会 STW
抓堆转储会停顿应用,大堆(>8G)可能停几十秒。生产环境优先用 jcmd PID GC.heap_dump -all=false,或提前配 HeapDumpOnOutOfMemoryError 让它在 OOM 时自动落盘。