JVMNotes

附录:附录:JVM 速查手册

zjc 于 2026-02-01 发布

这是《JVM 零基础实战指南》的独立章节版。本章从概念、实操和生产排查三个视角展开,代码块保留了原书可直接运行的版本。 本附录汇总本书常用命令、参数和排查路径,便于日常快速查阅。不同 JDK 版本和发行版的行为可能不同,生产使用前应以当前运行时输出和官方文档为准。

1. 常用命令

进程与基本信息

# 查看 Java 进程
jps -l

# 查看系统进程
ps -ef | grep java

# 查看 JVM 启动参数
jcmd <pid> VM.command_line

# 查看最终 flags
jcmd <pid> VM.flags

# 查看所有 flags
java -XX:+PrintFlagsFinal -version

内存与 GC

# 堆信息
jcmd <pid> GC.heap_info

# GC 概览
jstat -gc <pid> 1000
jstat -gcutil <pid> 1000

# 类直方图,可能开销较大
jcmd <pid> GC.class_histogram

# 手动堆 dump
jcmd <pid> GC.heap_dump /data/dump/app.hprof

# 触发 Full GC,慎用
jcmd <pid> GC.run

线程与诊断

# 线程 dump
jcmd <pid> Thread.print > thread-1.txt
jstack <pid> > thread-1.txt

# 连续采集
for i in 1 2 3 4 5; do
  jcmd <pid> Thread.print > "thread-$i.txt"
  sleep 2
done

# JFR
jcmd <pid> JFR.check
jcmd <pid> JFR.start name=live settings=profile filename=/log/live.jfr maxsize=512m
jcmd <pid> JFR.dump name=live filename=/log/now.jfr
jcmd <pid> JFR.stop name=live

Linux 排查

# 进程 CPU
top -p <pid>

# 线程 CPU
top -H -p <pid>
ps -L -p <pid> -o pid,tid,%cpu,%mem,state,comm --sort=-%cpu

# 十进制线程号转十六进制
printf "%x\n" <tid>

# 系统指标
vmstat 1
pidstat -p <pid> -t 1
iostat -x 1

2. 常用 JVM 参数

内存

参数 用途
-Xms 初始堆
-Xmx 最大堆
-Xmn 新生代
-Xss 线程栈
-XX:NewRatio Old 与 New 比例
-XX:SurvivorRatio Eden 与 Survivor 比例
-XX:MaxMetaspaceSize 元空间上限
-XX:MaxDirectMemorySize 直接内存上限
-XX:SoftMaxHeapSize ZGC 等软堆目标

收集器

-XX:+UseSerialGC
-XX:+UseParallelGC
-XX:+UseG1GC
-XX:+UseZGC
-XX:+UseShenandoahGC   # 需运行时支持
-XX:MaxGCPauseMillis=50

CMS 相关:

JDK 状态
JDK 8 可用
JDK 9 deprecated
JDK 14 移除

容器

-XX:+UseContainerSupport
-XX:InitialRAMPercentage=60.0
-XX:MaxRAMPercentage=60.0
-XX:MinRAMPercentage=50.0
-XX:ActiveProcessorCount=4

容器内存预算:

容器 limit
  >= Heap
   + Metaspace
   + Thread stacks
   + Direct memory
   + CodeCache
   + Native memory
   + OS 余量

3. 日志配置

现代 JDK:

java -Xlog:gc*,safepoint:file=/logs/gc.log:time,uptime,level,tags:filecount=10,filesize=50m \
  -jar app.jar

JDK 8:

java -XX:+PrintGCDetails \
  -XX:+PrintGCDateStamps \
  -XX:+PrintTenuringDistribution \
  -Xloggc:/logs/gc.log \
  -XX:+UseGCLogFileRotation \
  -XX:NumberOfGCLogFiles=10 \
  -XX:GCLogFileSize=50M \
  -jar app.jar

OOM 证据:

-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=/data/dump
-XX:+ExitOnOutOfMemoryError

4. 工具速查

工具 用途
javap 查看字节码
jstat GC 统计
jmap 堆信息与 dump
jcmd 推荐 JVM 命令入口
jstack 线程 dump
jhsdb 调试服务
jfr 查看 JFR 事件
MAT 堆 dump 分析
JMC JFR 可视化
Arthas 在线诊断
GCEasy / GCViewer GC 日志可视化
async-profiler CPU 与分配采样

5. 字节码命令

# 编译
javac -g Demo.java

# 查看字节码
javap -c Demo.class

# 查看常量池和详细信息
javap -v Demo.class

# 查看私有成员
javap -p Demo.class

常见指令:

指令 含义
aload_0 加载 this
iload_1 加载第 1 个 int 参数
istore_1 保存 int 到局部变量
invokevirtual 调用虚方法
invokespecial 构造、private、super
invokestatic 调用静态方法
invokeinterface 调用接口方法
invokedynamic Lambda、字符串拼接等动态调用
new 创建对象
monitorenter 进入 monitor
monitorexit 退出 monitor

6. 线程状态

状态 含义
NEW 尚未启动
RUNNABLE 可运行,可能等待 CPU 或 Native IO
BLOCKED 等待 monitor
WAITING 无限期等待
TIMED_WAITING 限时等待
TERMINATED 结束

死锁特征:

thread A waiting to lock L1, held by B
thread B waiting to lock L2, held by A

处理方向:统一加锁顺序、缩小锁范围、tryLock 超时、拆分锁粒度、避免锁内 IO。

7. GC 选择速查

场景 起点
小内存、低并发 Serial
批处理、吞吐优先 Parallel
常见在线服务 G1
大堆、低停顿、资源充足 ZGC
发行版支持且压测通过 Shenandoah

G1 关键点:

Region 化堆
Young / Mixed / Full GC
Remembered Set
可设置停顿目标

ZGC 关键点:

着色指针
读屏障
并发整理
Allocation Stall
JDK 21 分代模式

8. OOM 类型速查

类型 方向
Java heap space 堆 dump、GC 日志、对象泄漏
GC overhead limit exceeded 存活对象高、堆余量不足
Metaspace 类加载器、动态类生成
Unable to create new native thread 线程数、栈大小、OS 限制
Direct buffer memory NIO、Netty、直接内存
Requested array size exceeds VM limit 超大数组
OOMKilled / exit 137 容器总内存超限

应急流程:

摘流量
  -> 保存日志和 dump
  -> 记录监控和事件
  -> 重启或替换
  -> 分析根因
  -> 灰度验证

9. CPU 高排查

1. top 判断 user/sys/iowait
2. top -H 找高 CPU 线程
3. printf 转十六进制
4. 线程 dump 搜索 nid
5. 判断业务 / GC / JIT 线程
6. JFR 或 Arthas 定位方法
7. 结合流量和数据特征
8. 修复后压测验证

Arthas:

dashboard
thread -n 5
thread -b
trace com.demo.Service method '#cost > 100' -n 10
watch com.demo.Service method params returnObj throwExp -x 2 -n 5
stack com.demo.Service method -n 5
stop

10. 内存泄漏常见来源

来源 特征
静态集合 Retained Heap 大且持续增长
ThreadLocal 线程池线程持有
监听器 未注销
无界缓存 key 持续增长
大查询 byte[]、ArrayList、String 巨大
ClassLoader 同名类大量重复加载
队列积压 生产快于消费

MAT 关键视图:

Histogram
Dominator Tree
Path to GC Roots
Leak Suspects
Thread Overview

重点指标:

Shallow Heap:对象自身大小
Retained Heap:回收该对象可释放总量

11. JFR 模板

启动时:

java -XX:StartFlightRecording=filename=/logs/app.jfr,settings=profile,maxsize=1g,maxage=6h,dumponexit=true \
  -jar app.jar

告警后:

jcmd <pid> JFR.dump name=<recording> filename=/logs/incident.jfr

看什么:

CPU Load
Execution Sample
Allocation Sample
Java Monitor Blocked
Thread Park
Garbage Collection
Safepoint
Exception Statistics

12. 容器检查清单

1. memory request 与 limit
2. CPU request 与 limit
3. -Xmx 或 MaxRAMPercentage
4. MaxMetaspaceSize
5. MaxDirectMemorySize
6. 线程数和 -Xss
7. ActiveProcessorCount
8. GC 日志目录挂载
9. dump 目录挂载
10. Java 进程能收到 SIGTERM
11. 优雅停机时间小于 terminationGracePeriodSeconds
12. 健康检查和就绪检查

推荐启动模板:

exec java \
  -XX:+UseContainerSupport \
  -XX:InitialRAMPercentage=60.0 \
  -XX:MaxRAMPercentage=60.0 \
  -XX:ActiveProcessorCount=4 \
  -XX:MaxMetaspaceSize=512m \
  -XX:MaxDirectMemorySize=1g \
  -XX:+HeapDumpOnOutOfMemoryError \
  -XX:HeapDumpPath=/data/dump \
  -XX:+ExitOnOutOfMemoryError \
  -Xlog:gc*,safepoint:file=/logs/gc.log:time,uptime,level,tags:filecount=10,filesize=50m \
  -XX:StartFlightRecording=filename=/logs/app.jfr,settings=profile,maxsize=512m,maxage=6h,dumponexit=true \
  -jar /app/app.jar

13. 监控指标

必须监控:

process_cpu
container_cpu_usage
container_cpu_throttling
container_memory_usage
jvm_heap_used
jvm_heap_committed
jvm_heap_max
jvm_gc_pause
jvm_gc_count
jvm_gc_time
jvm_metaspace
jvm_direct_memory
jvm_thread_count
jvm_class_loaded
safepoint_time
http_p50
http_p99
http_p999
error_rate

建议告警:

指标 方向
Full GC 大于 0 需关注
GC P99 超过延迟目标
Allocation Stall 大于 0
回收后 Old 持续增长
memory usage / limit 大于 85%
CPU throttling 持续增长
线程数 突增或接近上限
重启次数 异常增长

14. 排障模板

时间:
实例:
版本:
现象:

系统指标:
  CPU =
  Memory =
  Disk =
  Network =

JVM:
  Heap =
  GC =
  Threads =
  Metaspace =
  Direct memory =

证据:
  GC log =
  Thread dump =
  Heap dump =
  JFR =
  Business log =

分析:
  1.
  2.
  3.

根因:
修复:
验证:
预防:

15. 版本提醒

主题 重要差异
永久代 JDK 8 移除,使用 Metaspace
CMS JDK 14 移除
偏向锁 JDK 15 起 deprecated
ZGC JDK 15 转正,JDK 21 引入分代
虚拟线程 JDK 21 正式发布
JFR JDK 11 后开源并广泛可用

升级或迁移时,应重新压测,而不是假设参数和默认值完全兼容。

16. 快速判断表

现象 优先检查
OOM heap dump、GC 日志、大对象
OOMKilled 容器总内存、堆外
CPU user 高 线程栈、JFR 热点
CPU sys 高 上下文切换、锁、系统调用
GC 停顿高 收集器、堆、Live 数据
安全点等待高 长循环、大数组操作
线程 BLOCKED 锁持有者、临界区
线程池满 外部超时、队列、下游
启动慢 JIT、类加载、CPU limit
延迟毛刺 CPU throttling、GC、安全点