arthas的heapdump命令仅生成堆快照,不直接检测内存泄漏;需在老年代持续增长、oom前或低峰期执行两次间隔dump,并用mat/jhat分析支配树及gc roots。

Arthas 的 heapdump 命令本身不直接检测内存泄漏,而是生成堆快照(heap dump),后续需结合分析工具定位可疑对象。关键在于“什么时候 dump”和“怎么分析”,不是 dump 了就等于找到泄漏点。
什么时候执行 heapdump 最有效
内存泄漏通常表现为老年代持续增长、GC 后回收很少、OOM 前堆占用居高不下。应在以下时机触发:
- 系统运行稳定后,观察到
jstat -gc <pid></pid>中老年代(OU)缓慢但持续上涨,且多次 Full GC 后仍不下降 - 使用
dashboard或vmtool --action getInstances --className java.lang.OutOfMemoryError确认近期发生过 OOM 或频繁 CMS/ParNew GC - 在业务低峰期、排除瞬时大对象分配干扰后,执行两次间隔几分钟的 heapdump(如
heapdump /tmp/dump1.hprof和heapdump /tmp/dump2.hprof),便于对比增长对象
用 Arthas 正确执行 heapdump
注意路径权限、JVM 参数和命令细节:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 确保目标路径(如
/tmp)对 Java 进程用户可写;若报错Permission denied,换用/dev/shm或容器内挂载的卷 - Arthas 3.6.0+ 支持
--live参数:heapdump --live /tmp/live.hprof,只导出存活对象(跳过 GC 可回收对象),文件更小、分析更准 - 避免在生产环境无节制 dump:一次完整 heapdump 可能暂停应用数秒(尤其堆 > 4G),建议先用
vmtool --action getStaticField --className java.lang.Runtime --fieldName totalMemory粗略判断堆大小再决定是否 dump
dump 后必须做的三件事
Arthas 不提供图形化分析能力,dump 文件需导出后借助外部工具:
-
用 jhat 或 VisualVM 快速看 top 占用类:运行
jhat -port 7000 /tmp/dump.hprof,浏览器打开http://localhost:7000→ “Show heap histogram”,重点关注retained size大、实例数异常多的类(如byte[]、HashMap$Node、自定义缓存类) -
用 Eclipse MAT 做支配树(Dominator Tree)分析:导入 hprof 后选
Dominator Tree视图,按Retained Heap排序,展开可疑类 → 右键Path to GC Roots → exclude weak/soft references,查看谁长期持有这些对象 -
结合 Arthas 实时验证线索:比如 MAT 发现大量
com.example.UserSession实例未释放,立刻回 Arthas 执行sc -d *UserSession*查加载器,再用ognl '@java.lang.System@getProperty("user.dir")'定位配置路径,排查是否缓存未设过期策略或监听器未注销
比 heapdump 更轻量的初筛手段
很多泄漏问题无需 dump 就能快速定位:
- 用
vmtool --action getInstances --className com.example.CacheHolder --limit 10直接查特定类实例,加--include-external包含三方类加载器实例 - 执行
ognl -x 3 '#context=@org.springframework.context.ApplicationContext@getApplicationContext(),#context.getBean("cacheManager").getCacheNames()'(Spring 环境)确认缓存是否意外膨胀 - 运行
monitor -c 5 'com.example.service.UserService' queryById观察方法调用频次与返回对象生命周期是否匹配,辅助判断是否高频创建未释放资源
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










