Arthas启动失败主因是用户权限不一致或容器未暴露/proc,需切换用户或添加SYS_PTRACE权限;CPU飙升用thread定位热点线程并查完整堆栈;内存泄漏优先用vmtool/object而非heapdump;watch/trace有类加载和性能约束,无法修改字节码或拦截native方法。

Arthas 启动失败:找不到目标 Java 进程怎么办
Arthas 无法 attach 到进程,常见原因是 java 进程用户权限不一致,或进程运行在容器中未暴露 /proc。先确认当前用户能否看到目标进程:ps -ef | grep java;如果看不到,说明不是同一用户启动(比如应用用 app 用户跑,你用 root 登录但没切用户),此时需切换到对应用户再执行 as.sh。
容器场景下,Docker 启动时要加 --cap-add=SYS_PTRACE --pid=host(或更稳妥地用 --privileged),否则 arthas-boot.jar 会报 Unable to open socket file 或 No such process。K8s 中则需在 securityContext 里显式开启 capabilities: {ADD: [SYS_PTRACE]} 和 procMount: DefaultProcMount。
诊断 CPU 飙高:用 thread 定位热点线程
thread -n 5 能直接列出 CPU 占用前 5 的线程,配合 thread -n 5 -i 1000(每秒采样一次、持续 1 秒)可观察波动趋势。注意:输出中的 nid 是十六进制线程 ID,要转成十进制后去 jstack 日志里搜才对得上。
常见误操作是只看 thread 输出的栈顶方法,忽略它被谁调用。建议紧接着执行 thread <nid></nid>(把刚才的十六进制 nid 填进去)查看完整堆栈,重点看是不是某个循环、正则匹配、JSON 反序列化卡住了——这些在栈里通常表现为 java.util.regex.Pattern、com.fasterxml.jackson.databind.ObjectMapper.readValue 等高频嫌疑点。
立即学习“Java免费学习笔记(深入)”;
线上查对象内存泄漏:慎用 heapdump,优先用 object 和 vmtool
heapdump 会触发 Full GC 且生成 GB 级文件,生产环境基本不可行。更轻量的方式是:vmtool --action getInstances --className com.example.User --limit 10 查指定类实例;或 object --class-pattern User --stat 统计数量分布。
如果怀疑某类对象暴增,先用 dashboard 观察老年代使用率和 YGC 次数是否同步上升;再用 jvm 看 usedMemory 和 maxMemory 差值是否持续收窄;最后结合 ognl '@java.lang.management.ManagementFactory@getMemoryMXBean().getHeapMemoryUsage()' 获取实时内存用量,交叉验证。
修改线上逻辑又不想重启?watch 和 trace 的真实约束
watch 默认只监听已加载类的方法,如果目标类是运行时动态生成(如 MyBatis Mapper 接口代理类、Lombok 生成的 getter),需加 -x 3 参数展开深层字段,且必须确保该类已被 JVM 加载(可通过 sc -d *Mapper 确认)。
trace 对性能影响明显,尤其在高 QPS 接口上,单次 trace 可能增加毫秒级延迟。建议限定范围:trace -E com.example.service.*Service\.(do|handle).*,避免用 com.example..* 这种宽泛表达式。另外,trace 不支持 lambda 表达式内部方法,遇到 java.lang.invoke.LambdaMetafactory 相关栈,得回退到源码加日志或改用 jad 反编译确认逻辑流。
Arthas 再强大也绕不开 JVM 限制:它不能修改字节码结构(比如新增字段)、不能绕过 final 修饰符、不能拦截 native 方法。真正卡死的线程(如 JNI 死锁、文件句柄耗尽)靠它只能发现现象,解法还得回到系统层排查。


















