Arthas JVM 性能排查
一、官方资源
- 官网
- IDEA 插件支持命令生成,提高排查效率。
- 官方文档包含完整命令说明、示例与在线教程。
二、常用命令分类
1. 类相关命令
命令 | 功能说明 |
---|---|
getstatic | 查看类静态属性,可结合 ognl 遍历复杂对象 |
jad | 反编译已加载类源码,可指定 ClassLoader 和方法 |
retransform | 加载外部 .class 替换已加载类,支持查看和删除 entry |
redefine | 动态替换类方法字节码 |
2. 监测排查命令
命令 | 功能说明 |
---|---|
monitor | 方法调用监控(次数、耗时、异常) |
stack | 查看方法调用路径 |
thread | 查看线程堆栈和状态,支持阻塞线程分析 |
trace | 方法内部调用路径及耗时分析 |
tt | 时空隧道,记录方法入参和返回值 |
watch | 方法执行数据观测,支持 -b/-e/-s/-f 四个事件 |
3. JVM 相关命令
命令 | 功能说明 |
---|---|
heapdump | 生成堆转储文件,用于 MAT/VisualVM 分析 |
jfr | Java Flight Recorder,低开销采集诊断数据 |
memory | 查看 JVM 内存使用情况 |
dashboard | 实时系统监控 |
classloader | 查看 ClassLoader 及继承树 |
logger | 查看及更新 Logger |
sc | 查看已加载类信息 |
mbean | 查看 MBean 属性及监控 |
profiler | 生成火焰图分析热点方法 |
vmoption | 查看及更新 VM 参数 |
vmtool | 查询对象实例、强制 GC、线程操作 |
4. 特殊与辅助命令
命令 | 功能说明 |
---|---|
ognl | 执行 OGNL 表达式,灵活访问对象属性 |
options | 设置全局开关(如 JSON 输出、unsafe 模式等) |
help | 查看命令帮助 |
history | 命令历史 |
cls | 清屏 |
quit | 退出连接 |
stop | 完全退出 Arthas |
reset | 重置增强类 |
三、OGNL 表达式常用语法
- 访问静态属性:
@全路径类@静态属性
- 调用静态方法:
@全路径类@方法("参数")
- 条件过滤:
params[0].{? #this.name != null}
- 构造对象:
new com.Test("xiaoming", 18)
- 临时变量:
#var=@com.Test@getPerson("xiaoming",18)
💡 Tips:结合 grep
使用命令过滤结果,例如:
classloader -a | grep "String"
四、JVM 垃圾收集与调优
1. 核心概念
- 分配速率 (Allocation Rate):新生代对象分配速度,单位 MB/s
- 提升速率 (Promotion Rate):新生代对象晋升到老年代的速度,单位 MB/s
- 调优目标:短命对象在新生代回收,长寿对象晋升到老年代,避免频繁 GC 或 OOM。
2. 新生代调优
- 计算公式:
Allocation Rate = (本轮GC前使用容量 - 上轮GC后容量) / 时间差
- 高分配速率 → GC 频繁 → 吞吐量下降
- 调优策略:减少对象创建,或增大新生代堆空间
3. 老年代调优
- 计算公式:
Promotion Rate = (新生代减少量 - 整堆减少量) / 时间差
- 高提升速率原因:内存泄漏、大对象频繁分配、高并发流量冲击
- 调优策略:延迟晋升,保持对象在新生代多轮 GC 后再进入老年代
4. 堆空间分配建议
- 新生代适当增大,减少 Minor GC
- 老年代保持足够空间,避免 Full GC
- 根据活跃数据量合理分配各区域大小
5. GC 流程示意
新生代 (Eden + Survivor)┌─────────┐│ Eden区 │ ← 高分配速率,新对象优先分配├─────────┤│ Survivor │ ← 新生代对象存活若干轮 GC 后晋升└─────────┘││ 晋升 (Promotion)▼
老年代 (Tenured)┌─────────┐│ 老年代 │ ← 对象长寿命存储区,Full GC 触发└─────────┘GC 流程:
[Minor GC] → 清理 Eden & Survivor → 存活对象晋升到老年代
[Major/Full GC] → 清理老年代
五、Arthas 命令速查表(场景化)
场景/目标 | 常用命令 | 使用建议与说明 |
---|---|---|
JVM 基本信息 | dashboard | CPU、内存、线程、GC 全景 |
vm | 查看 JVM 内存、GC、类信息 | |
线程排查 | thread | 查看线程状态及堆栈 |
thread -n 3 | CPU 占用前 3 的线程堆栈 | |
方法耗时分析 | monitor -c 3 类名 方法名 | 监控方法执行耗时及调用次数 |
trace 类名 方法名 | 方法调用链追踪 | |
热点方法 & CPU 分析 | tt 类名 方法名 | 采样 CPU 占用,定位热点方法 |
内存泄漏排查 | heapdump | 导出堆快照分析 |
object 类名 | 查看对象实例数量与大小 | |
类信息 & ClassLoader | sc | 查看加载的类信息 |
cls 关键字 | 按关键字过滤类 | |
AOP/动态修改 | redefine | 动态替换类方法字节码 |
ognl | 在 JVM 内执行表达式 | |
日志 & 配置调试 | jad 类名 | 反编译 class 查看源码 |
watch 类名 方法名 | 方法调用前后拦截,打印参数/返回值 |
💡 建议排查顺序:
dashboard
→thread
→monitor/trace
→heapdump/object
→ognl/redefine
六、性能问题实战示例
场景:线上 CPU 突然飙高
-
查看 JVM 状态:
dashboard
-
找出 CPU 占用高线程:
thread -n 5
-
分析热点方法:
tt -t 10 类名 方法名
-
监控方法耗时与调用次数:
monitor 类名 方法名 -c 5
-
排查内存泄漏(如伴随内存增长):
object 类名 heapdump
-
临时监控参数或返回值:
watch 类名 方法名 '{params, returnObj}' -x 3