说说 JVM 的堆转储文件以及获取方式
JVM 的堆转储文件(heap dump)是某个时间点、Java 进程的内存快照。包含了当时内存中还没有被 full GC 回收的对象和类信息。
1 文件内容
堆转储文件包含以下内容:
- 所有对象 - 对象所对应的类、字段、原生数据类型以及引用。
- 所有类 - Classloader、类名、超类以及静态字段。
- 垃圾回收器的根 - Java 垃圾回收就是使用它,进行可达性分析,从而判定一个对象是否可以被回收。
- 线程堆栈与本地变量。
因为堆转储文件没有保存共享信息,所以找不到对象创建者信息。
2 自动生成模式
我们可以在 JVM 中配置 -XX:+HeapDumpOnOutOfMemoryError
,这样在发生内存溢出异常(OutOfMemoryError)时,就会在工作目录中,自动生成堆转储文件。
3 手动生成模式
3.1 jmap 命令
jmap -dump:format=b,file=<filename.hprof> <pid>
- 其中的 format=b,表示转储为二进制格式。
- file 指定转储文件的路径,后缀为 hprof。
- pid 表示进程 ID。
在 windows cmd 中,可以使用命令 tasklist 来查看进程 ID。
3.2 jconsole 控制台
Jconsole (Java Monitoring and Management Console),是 JDK 自带的监控 、管理工具 。
首先双击 ${JDK_HOME}/bin/jconsole.exe,打开进程连接列表,选择我们需要 dump 的进程:
默认是使用 SSL,本地一般不会用到,所以这里直接选择 “不安全的连接”:
连接成功后,就会进入监控概览:
依次选择 MBean → com.sun.management 下 HostSpotDiagnosic 中的 dumpHeap,在 p0 中输入 hprof 文件的导出路径,这样就可以生成堆转储文件啦:
3.3 Eclipse Memory Analyzer
也可以使用 Eclipse Memory Analyzer,直接从进程中生成堆转储文件。打开 Memory Analyzer,点击右上角的 File → Acquire Heap Dump,这时就会打开本地进程列表,我们选择想要 dump 的进程,并指定好堆存储路径:
点击 Next ,就会进入 Heap Dump Provider 参数配置页,在此我们可以配置导出的类型、是否只导出活跃对象、是否压缩以及制定导出路径参数:
个人更喜欢 jmap 命令,简单、清晰。