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

Linux指令实战学习之内存泄漏

1. 如何快速定位内存泄漏?

定位内存泄漏一般可以分三步走。

1.1 确认是否真的泄露

最简单的方式是通过如下指令确认:

jstat -gcutil pid 1000

接下来让我分析一下指令含义:

首先是jstat,它JDK自带工具,不在系统自带命令集,必须满足两点:

a. 服务器/本机安装了JDK(不是只装JRE),配置好环境变量

b. 命令执行终端和Java进程在同一操作系统的用户下(root进程普通用户看不到,会报找不到进程)

然后就是配套参数:

  • gcutil:打印GC统计百分比(使用率、回收次数、耗时),最常用的GC监控参数;
  • pid:目标Java应用进程 ID;
  • 1000:采样间隔,单位毫秒,每 1000ms(1 秒)输出一行数据;
  • 无末尾数字 = 只输出1次,加数字 = 持续滚动输出。

直观效果:

终端会每秒刷新一行GC指标,持续打印,直到手动按Ctrl+C终止命令。 用于实时观察堆内存占用、GC 频率、STW 耗时,排查内存泄漏、频繁 FullGC、OOM 问题

标准输出样例:

S0 S1 E O M CCS YGC YGCT FGC FGCT GCT 0.00 22.35 45.21 18.64 92.10 88.32 123 1.456 2 0.872 2.328

字段解释:

字段含义
S0Survivor0 区内存使用率 %
S1Survivor1 区内存使用率 %
EEden 新生代使用率 %
OOld 老年代使用率 %
MMetaspace 元空间使用率 %
CCS压缩类空间使用率
YGC年轻代 GC(Minor GC)总次数
YGCT所有 Minor GC 总耗时(秒)
FGCFull GC 总次数
FGCT所有 Full GC 总耗时(秒)
GCT程序启动以来 GC 总耗时

观察GC情况:

如果老年代内存使用率一直涨,执行Full GC后也降不下来,那基本就是有内存泄漏了。或者看监控曲线,内存一直往上走,呈现锯齿状但低点越来越高,这就是典型特征。

1.2 通过dump堆快照导出对象

指令如下:

jmap -dump:live,format=b,file=heap.hprof pid

接下来让我分析一下指令含义:

首先是jmap,它是JDK自带堆快照工具,用于导出Java进程堆内存文件,以便离线分析内存泄漏、大对象、OOM

它的使用条件同jstat一致。

-dump:

代表执行堆转储(dump堆快照),后面跟多个配置参数,用逗号分隔。

参数逐项解析:

live:

只导出当前存活对象,它会先触发一次FullGC,把已经没有引用垃圾对象过滤掉,快照文件更小、分析更干净。

如果去掉live,就会导出全量堆,包含已死亡未回收对象,文件更大。

format=b:

固定写法,b= binary二进制格式,标准hprof二进制文件,是MAT、JProfiler、IDEA内存分析工具通用格式,不可省略。

file=heap.hprof:

指定导出的文件名heap.hprof,文件生成在当前执行命令的目录,可自定义路径,例如file=/tmp/heap_20260704.hprof

pid:

目标 Java 进程号,可以用“ jps -l ”或者“ ps -ef | grep java ”获取。

执行后效果:

a. 程序会暂停STW(Stop-The-World),堆越大停顿越久,线上业务高峰期慎用

b. 磁盘生成.hprof二进制堆文件

c. 导出完成后终端输出完成提示,Java进程恢复正常运行。

如果担心OOM突然发生来不及dump,可以提前加JVM参数-XX:+HeapDumpOnOutOfMemoryError,这样OOM时会自动dump

1.3 用MAT分析(也可选择其他内存分析工具)

Eclipse Memory Analyzer,打开.hprof文件后它会自动给一个Leak Suspects报告,通常能直接定位问题。

如果报告不够明确,可以看Histogram视图,找到实例数量特别多或者占用内存特别大的对象,然后右键选择Path to GC Roots,选exclude weak references,这样就能看到是哪些强引用持有了这个对象导致它回收不了。

比如说你可能看到某个静态HashMap持有了这些对象,或者被ThreadLocal持有,问题就很清楚了。

1.4 总结

还有个实用技巧是对比两次堆快照

间隔一段时间dump两次,用MATCompare功能对比,增长最多的对象往往就是泄漏的对象,这对缓慢泄漏的问题特别有效。

如果是本地环境调试,可以直接用JProfiler实时监控,能看到内存实时分配情况对象引用关系,比dump快照更直观。

基本上这套流程下来,大部分内存泄漏都能定位到。

关键就是先确认有泄漏,然后dump堆快照,最后用MAT分析GC Roots引用链,找到是哪里的代码持有了不该持有的引用。

大多数遇到的内存泄漏问题,十有八九都是静态集合没清理ThreadLocal没remove或者监听器没反注册这几种情况,看到引用链基本就能马上判断出来。

http://www.gsyq.cn/news/1637661.html

相关文章:

  • 堪萨斯大学新研究:揭示读唇出错原因,有望提升读唇训练与AI转录能力
  • 小模型回到电脑本地,数据安全就自动解决了吗?
  • 一颗Codec芯片的生存法则:为什么AI语音产品需要TP9311?
  • 图像哈希算法(aHash/dHash/pHash)Python实战:3种方法对比与汉明距离阈值调优指南
  • 每个按键都能单独屏蔽!这款免费小工具,治好了我的误触强迫症
  • 生命涌现的小龙虾技能之【Cat Face Recognition Skill | 猫脸识别技能】简介
  • 虚拟化技术深度解析:从底层原理到产业实践,读懂云计算的核心基石
  • ARIMA 模型定阶实战:基于 ACF/PACF 图的 4 种典型模式识别与 p, q 值选择
  • CubeSandbox 线下体验
  • 电脑磁盘分区|C盘爆红|实现过程中出现的问题并解决
  • mcntools - Minecraft 模组 JAR 文件硬编码翻译工具
  • GitHub 热榜项目 - 周榜(2026-07-04)
  • 机器人5公里长跑背后的技术:强化学习与模型预测控制如何实现动态平衡
  • 企业微信会话存档SDK实战——跨平台部署与动态库加载避坑指南
  • 牛计数数据集 | 3300张YOLO智慧畜牧数据集
  • YOLOv8与卡尔曼滤波融合:构建实时目标检测与跟踪系统
  • 英伟达AI Compute Partnership:从“卖铲人“到“收租人“的算力金融化革命
  • Codex桌面客户端:零代码接入DeepSeek等大模型,打造本地AI助手
  • CubeSandbox 快照、克隆、回滚部署实操体验|OC城市行深圳站
  • 剑星 全内容 中文全DLC 脱离虚拟机 即点即玩
  • 我在腾讯云 CVM 上实操 CubeSandbox:从部署到体验快照、克隆和回滚分享
  • 好无聊上班的一天
  • 学习嵌入式Day3
  • 从粉丝项目到技术实践:构建自动化内容管理流水线
  • 实战指南:如何用开源工具永久保存你的QQ空间数字记忆
  • 救命!UniApp上架App Store踩4.3a红线,我靠这招3天逆袭过审了[特殊字符]
  • Fable 5复活引争议!“内心戏”暴露,AI意识大讨论升温!
  • 基于大数据爬虫+Hadoop用户偏好迁移的电影推荐系统
  • 斯坦福CS231n计算机视觉课程:从理论到Kaggle实战的完整指南
  • eclipse ditto 学习笔记