1. 查看heap(堆)内存中的实例数量和占用内存的大小
命令:
jmap -histo JVM进程ID
直接使用上面的命令,打印的东西太多,可以使用下面的命令只显示前50行:
jmap -histo JVM进程ID | head -n50
或者使用下面的命令,通过翻页的方式查看:
jmap -histo JVM进程ID | more
如果想 只统计存活的对象 ,可以使用下面的命令,该命令会 先触发JVM执行GC(垃圾回收),然后再统计信息 :
jmap -histo:live JVM进程ID
2. 查看类加载相关的信息
命令:
jmap -clstats JVM进程ID
同样可以结合head
和more
命令使用,避免一次打印的信息太多,导致严重的翻页。
3. 输出dump文件
命令:
jmap -dump:live,format=b,file=jvm_heapLive.hprof JVM进程ID
format=b : 表示以二进制格式导出文件
file=XXX : 导出的dump文件路径和文件名称
执行该命令的时候会将整个JVM上面的所有线程都暂停,如果java堆比较大,例如有几十GB,那么暂停的时间就比较长,有可能长达几十分钟,所以在生产环境上要慎用这个命令。
上面的命令导出的文件是二进制的文件,人肯定是看不懂的。需要借助 Memory Analyzer (MAT) 之类的dump文件分析工具才能看懂。
4. MAT工具的简单使用
如果堆内存比较大,那么在使用MAT工具进行分析时,需要先调整MAT工具的内存,否则工具无法解析。找到 MemoryAnalyzer.ini
文件,调整内存大小:
双击MemoryAnalyzer.exe
,工具启动后,选择菜单File
-> Open Heap Dump
,然后选择导出的dump文件,建议将dump文件放在一个单独的目录下面,因为在解析的过程中,工具会自动生成好多文件。等待工具解析完成:
解析结果,点击Reports
下的选项,可以生成报告,例如点击Leak Suspects
:
拉到报告的最下方,点击Table Of Contents
可以进入报告的目录:
在目录页面,想看什么就选择什么,例如想看线程信息,想看占用内存最多的对象:
线程信息:
占用内存最多的对象:
点击Actions
里面的Dominator Tree
,可以查看内存中的对象信息:
对象树:
MAT工具用起来还是比较简单的,自己多摸索摸索就会了。