当前位置: 首页 > news >正文

【死磕JVM】用Arthas揪出内存泄漏元凶:从监控到定位的实战指南

1. Arthas简介与内存泄漏排查场景

第一次接触Arthas是在一个深夜的线上告警中——我们的订单服务内存占用突然飙升到90%。当时用jmap导出的堆转储文件足足有8GB,MAT分析到一半就直接OOM了。后来团队里的架构师扔给我这个阿里开源的诊断工具,我才发现原来排查JVM问题可以这么优雅。

Arthas最让我惊艳的是它的实时交互能力。不像传统工具需要停机分析,它能在应用运行时直接挂载诊断,通过命令行交互查看内存、线程、类加载等信息。特别是排查内存泄漏时,memory命令能实时观察堆内存变化,heapdump生成的文件也比jmap小很多。有次我仅用200MB的堆转储就定位到了ThreadLocal泄漏问题。

常见的内存泄漏场景主要有三种:

  • 集合类持有引用:比如全局的HashMap不断添加缓存对象
  • 线程池堆积任务:像我们遇到的订单处理线程池阻塞
  • 未关闭的资源:数据库连接、文件流等

2. 环境准备与问题复现

2.1 模拟内存泄漏案例

先准备一个故意制造泄漏的Demo(完整代码见GitHub):

public class MemoryLeakDemo { static List<byte[]> leakList = new ArrayList<>(); // 泄漏容器 public static void main(String[] args) throws Exception { while (true) { leakList.add(new byte[1024 * 1024]); // 每秒泄漏1MB Thread.sleep(1000); } } }

启动时加上内存限制参数:

java -Xms100m -Xmx100m MemoryLeakDemo

2.2 Arthas快速接入

下载并启动Arthas:

wget https://arthas.aliyun.com/arthas-boot.jar java -jar arthas-boot.jar

看到控制台输出目标进程时,输入对应编号即可挂载。我常用的是dashboard命令,它能实时显示:

Memory used total max usage heap 65M 256M 1024M 6.37% nonheap 45M 62M -1 72.58%

3. 实时内存监控与分析

3.1 memory命令深度使用

输入memory会显示关键内存区域数据:

Memory used total max usage heap 78.3MB 100.0MB 100.0MB 78.3% nonheap 35.2MB 56.0MB -1 62.8% codeheap 'non-nmethods' 3.4MB 5.0MB 68.0%

重点关注Old Gen区的增长趋势。如果持续上升不回落,很可能存在泄漏。我一般会配合-i参数定时采样:

memory -i 5000 # 每5秒刷新一次

3.2 堆内存快照生成

当发现Old Gen异常时,立即用heapdump保存现场:

heapdump /tmp/demo.hprof

这个命令比jmap更安全:

  1. 不需要指定进程ID
  2. 默认会进行压缩
  3. 支持只dump存活对象

4. 堆转储文件分析实战

4.1 MAT基础分析

用Eclipse Memory Analyzer打开dump文件,重点关注:

  1. Histogram:按类统计实例数
  2. Dominator Tree:显示对象引用链
  3. Leak Suspects:自动分析泄漏点

4.2 OQL查询技巧

在MAT中使用OQL定位大对象:

SELECT * FROM byte[] WHERE toString(runtimeClass).contains("MemoryLeakDemo")

这个语句能快速找到我们Demo中泄漏的byte数组。

5. 进阶内存诊断技巧

5.1 结合jvm命令

查看GC详细情况:

jvm -gc

输出示例:

G1 Young Generation: Eden Space: [0x00000000f0c00000,0x00000000f0c01000,0x00000000f0d00000) Survivor Space: [0x00000000f0d00000,0x00000000f0d00000,0x00000000f0e00000)

5.2 监控特定类

用sc命令查看类加载信息:

sc -d *MemoryLeakDemo

输出会显示类加载器、来源JAR包等关键信息。

6. 内存问题修复与验证

找到泄漏点后,常见的修复方式有:

  1. 修复集合引用:改用WeakHashMap
  2. 清理线程局部变量:及时remove() ThreadLocal
  3. 资源关闭:实现AutoCloseable接口

修复后可以用jmap -histo:live验证对象是否被回收。

记得有次修复一个缓存泄漏后,堆内存从4G直接降到800MB,那种成就感比写完十万行代码还爽。建议每次修复后持续监控24小时,有些泄漏是定时任务触发的。

7. 生产环境注意事项

  1. 安全限制:用--target-ip限制访问IP
  2. 性能影响:heapdump时暂停线程,避开高峰
  3. 权限控制:禁止普通用户执行高危命令

推荐在预发环境充分测试,我用Arthas排查过的线上问题,从没因为工具本身引发故障。

http://www.jsqmd.com/news/1194694/

相关文章:

  • 宝玑官网售后服务,腕表维修与保养服务权威公示(2026年7月最新) - 亨得利钟表维修中心
  • 查询|2026 上海劳力士官方售后地址及维修预约电话(2026年7月最新版) - 劳力士中国维修中心
  • Uncle小说阅读器:重新定义PC端数字阅读体验的三大技术突破
  • 如何快速搭建Java电商系统:基于Spring Boot和Vue的完整解决方案
  • PalEdit:3大场景解锁你的PalWorld存档编辑超能力
  • 构建企业级高分辨率说话人脸生成架构:HDTF深度技术实现指南
  • 杭州吟颂:职称评审申报要点全解析
  • 2026今日金价是多少,大连沙河口区易奢福黄金高价回收 - 肉松卷
  • 科大讯飞办公本三款机型深度对比:教师、律师、顾问如何选?
  • 融合PLUS-InVEST模型与地理探测器:生态系统服务多情景模拟与驱动机制解析
  • 企业级IM即时通讯系统|稳定、安全、高效的沟通解决方案
  • GreaterWMS:企业级开源仓库管理系统的完整实践指南
  • 【小程序毕业设计】基于 微信小程序的食堂订单管理系统 基于 小程序的智慧校园餐饮点餐系统的设计与实现(源码+文档+远程调试,全bao定制等)
  • 终极指南:如何5分钟搞定LXMusic音源配置,畅享免费全网音乐
  • Wan-Dancer-14B故障排除手册:常见问题与解决方案大全
  • 2026年专业级信号发生器品牌排行 主力产品实力对比 - 互联网科技品牌测评
  • CSP - 2023 普及组初赛试题及解析
  • 双电源自动切换电路设计与工程实践
  • 济南百年灵中国官方售后服务门店 | 最新维修地址及电话权威收录(2026 年 7 月最新) - 亨得利客户服务中心
  • 2026年7月亨得利官方全新服务体系与售后统一热线全解析 - 亨得利维修保养中心
  • Cursor AI视图切换私密配置库(仅限核心用户流通):含11个未文档化API调用示例、3类自定义View Provider注册模板
  • Python深入浅出:从入门到工程实践21
  • 小程序毕业设计-基于微信小程序的智能购物助手与价格比较系统的设计与实现 基于微信小程序的网购商品比价服务系统(源码+LW+部署文档+全bao+远程调试+代码讲解等)
  • 三步解决小说资源难题:Uncle小说PC版的智能下载与阅读体验
  • 终极免费彩色表情字体:EmojiOne Color 完整使用解决方案
  • 2026年新开合击服品牌推荐:神月传奇打造公平无套路体验 - 全域品牌推荐
  • 2026 年秦皇岛欧米茄手表回收品牌恒益奢品汇官方联络信息公示 - GrowUME
  • 从X86到飞腾:多架构主板设计核心要点与实战调试指南
  • unizip开发者手册:从源码结构到贡献代码的完整路径
  • 普洱主城区黄金回收门店实测调研及消费避雷攻略 - 天天开心12