如何在 Java 中进行内存泄漏分析?
如何在 Java 中进行内存泄漏分析?
回答重点
先确认是否真的发生了内存泄漏,即观察内存使用情况。
利用 jstat 命令(jstat -gc <pid> <interval in ms> )来观察 gc 概要信息,如果发现 GC 后内存并没有明显的减少且还是持续增加持续触发 gc,那说明内存泄漏的概率很大。
此时可以利用 jmap(jmap -dump:format=b,file=heapdump.hprof <pid>)生成 heap dump,然后将其导入 Eclipse MAT 或者 VisualVM 工具内进行分析,通过大量内存的占用可以找到对应的对象。
通过对象找到对应的代码分析,确认是否可能存在内存泄漏的场景,最终修复代码,解决内存泄漏的问题。
扩展知识
Eclipse Memory Analyzer (MAT)
Eclipse Memory Analyzer (MAT) 是一个强大的 Java 堆分析工具,主要用于查找和解决内存泄漏问题。
主要功能:
1)堆转储分析:
- 支持分析
.hprof格式的堆转储文件,生成对象的详细视图和引用路径。
2)泄漏检测:
- 自动检测内存泄漏,提供泄漏报告,帮助开发者定位问题对象。
3) 对象查询:
- 使用 OQL(Object Query Language)对对象进行查询,快速查找特定对象。
4) 视图和图表:
- 提供对象分布图、保留集分析等可视化功能,帮助理解内存使用情况。
5)整合:
- 可以与 Eclipse IDE 集成,方便开发者直接在开发环境中进行分析。
使用方法:
- 生成堆转储:使用
jmap -dump命令生成.hprof文件。 - 导入文件:在 MAT 中打开堆转储文件,进行分析。
- 使用自动分析功能获取泄漏信息,查看对象引用路径和内存占用情况。
VisualVM
VisualVM 是一个功能强大的 Java 性能监控和故障排除工具,提供实时监控和分析功能。
主要功能:
1)实时监控:
- 实时查看 CPU 使用率、内存占用、线程活动等,监控应用的运行状态。
2)堆转储和分析:
- 支持生成和分析堆转储,查看内存使用情况和对象分布。
3)线程分析:
- 提供线程视图,能够显示线程状态、线程栈信息,帮助识别死锁和高 CPU 使用的线程。
4)插件支持:
- 支持通过插件扩展功能,提供更灵活的监控和分析选项。
5)JMX 监控:
- 能够监控 JMX 代理的 Java 应用,获取各种运行时指标。
使用方法:
- 启动 VisualVM:在终端运行
jvisualvm。 - 选择目标 Java 应用:在主界面选择要监控的 Java 进程。
- 使用“监控”选项卡查看实时数据,使用“堆转储”选项生成和分析堆转储。
jstat
Java 自带的命令行工具,主要用来监控 JVM 中的类加载、GC、线程等信息。
附 jstat 输出字段解释:
- S0C/S1C/S0U/S1U: 年轻代中Eden区、Survivor区1和Survivor区2的容量(Capacity)和使用量(Used)。
- EC/EU: 年轻代中Eden区的容量和使用量。
- OC/OU: 老年代的容量和使用量。
- MC/MU: 方法区的容量和使用量。
- CCSC/CCSU: 压缩类空间的容量和使用量。
- YGC: 年轻代GC的次数。
- YGCT: 年轻代GC所用的时间。
- FGC: 老年代GC的次数。
- FGCT: 老年代GC所用的时间。
- GCT: 总的GC时间。
怎么分析 JVM 当前的内存占用情况?
Comments