当前位置: 首页 > 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.jsqmd.com/news/1125682/

相关文章:

  • 堪萨斯大学新研究:揭示读唇出错原因,有望提升读唇训练与AI转录能力
  • 小模型回到电脑本地,数据安全就自动解决了吗?
  • 1D-CNN 轴承故障诊断实战:CWRU 数据集 6 类识别准确率达 99.2%
  • 小米寥寥几家车企设计汽车顶棚
  • 数智驱动 全域增长:劲捷KINGJOY的跨界突围与全域增长之路
  • 一颗Codec芯片的生存法则:为什么AI语音产品需要TP9311?
  • Agent 需要拦截模型调用?用 Middleware 给它加个“拦截器“!
  • 图像哈希算法(aHash/dHash/pHash)Python实战:3种方法对比与汉明距离阈值调优指南
  • 2026真太阳时八字排盘工具怎么选:看出生地校正、时区口径和隐私边界
  • HLS Downloader:浏览器里直接抓取和下载直播流
  • QT 5升级到 Qt 6 使用 Clazy 检查将 C++ 应用程序移植到 Qt 6
  • 生命涌现的小龙虾技能之【Cat Face Recognition Skill | 猫脸识别技能】简介
  • 每个按键都能单独屏蔽!这款免费小工具,治好了我的误触强迫症
  • 客户拜访录制了需求沟通短视频,2026教你搞定短视频文字提取难题
  • 速卖通商品信息自动翻译实现方案
  • 基于YOLO与边缘计算的垃圾自动分类系统:从数据到部署全流程实践
  • 新人接手老仓库最怕没人带:用 Codex / Claude Code 先画一张代码地图
  • 2026智能门锁避坑白皮书:从“参数内卷”到“6条标准”,不花冤枉钱的选购清单
  • 终极免费音频编辑解决方案:Audacity 完整指南
  • 每日热门skill:你的OpenClaw还在“闭着眼“搜索?Desearch这套去中心化引擎,让AI搜索质量飙到92.6%
  • 终极GitHub下载加速指南:3分钟解决国内访问缓慢问题
  • 虚拟化技术深度解析:从底层原理到产业实践,读懂云计算的核心基石
  • 视频剪辑神器,免费实用
  • ARIMA 模型定阶实战:基于 ACF/PACF 图的 4 种典型模式识别与 p, q 值选择
  • 安卓手游画质助手 解锁VIP功能「Android」
  • CubeSandbox 线下体验
  • 终极STL转STEP转换指南:5分钟实现3D格式无缝对接
  • python教程入门(二、第一个python程序)
  • 智能场假说:共振动力学与物理具身的统一框架(源自实验室科研工作感触)
  • 终极解决Realtek 8922AE WiFi 7网卡驱动问题的完整实战指南