jmap 转存堆文件时会引发进程停顿
# hprof 格式
jmap -dump:file=***.hprof <pid>
# 二进制格式
jmap -dump:format=b,file=***.bin <pid>
# json 格式
jmap -dump:format=json,file=***.json <pid>
# 文本格式
jmap -dump:format=text,file=***.txt <pid>
jmap 的基本工作流程
- jmap 会向 jvm 发送一个命令,请求 jvm 生成一个 JAVA 堆转储快照,可以在命令选项中指定 '-dump:live',也就是只生成存活对象的堆转储快照,而不包括已经被回收的对象
- jvm 收到 jmap 请求后,会开启线程执行操作。在这个过程中,jvm 会停止应用程序的运行(STW),直到快照生成。这意味着要在生产环境谨慎使用该命令
- 生成 java 堆转储快照后,会保存到一个文件中,可以指定为txt,b,json,hprof等多种格式
分析转储文件的工具
- MAT (Memory Analyzer Tool)
- JVisualVM java自带的分析工具,提供堆分析、对象分析、类分析
- YourKit
- JProfiler 商业级java分析工具
生成转储文件,导致 jvm 卡顿怎么办
由于使用 jmap 生成转储文件,需要遍历整个 java 堆内存,java 进程的卡顿或延迟是难以避免的。 不过可以注意jmap的使用方式,尽量降低这些影响:
- 选择合适的 jmap 参数:使用"-dump:live" 会触发一次 Full GC ,所以要避免使用。要在生产环境中使用,尽量在低峰期或非常紧急的情况下使用;
- 限制 jmap 命令的生成范围,使用 "-histo:live",只会触发部分 GC,不过影响虽然相对较小,但也不能随意使用,尽量在低峰期或非常紧急的情况下使用;
# 生成直方图
jmap -histo:live <pid> > histo.txt
- 使用 jcmd 命令代替 jmap 。类似于jmap,但可以在不停顿 java 进程的情况下执行;
- 如不是危急情况,最大程度避免在生产环境使用 jmap,如要使用请通知相关人做好准备,最好准备好灾难应对措施。
补充
jcmd 的介绍 命令格式:
jcmd <pid> <command> [<arguments>]
# 生成目标进程的堆转储文件,并输出到指定文件
jcmd <pid> GC.heap_dump -all thread_dump.hprof
其中,"<pid>" 是目标 Java 进程的进程 ID,"<command>" 是要执行的命令,"<arguments>" 是命令的参数。
常用的 jcmd 命令:
- jcmd VM.version:显示目标 Java 进程的版本信息。
- jcmd VM.flags:显示目标 Java 进程的命令行参数和 JVM 标志。
- jcmd GC.run:强制目标 Java 进程执行一次 Full GC。
- jcmd GC.heap_dump :生成目标 Java 进程的堆转储文件。
- jcmd Thread.print:打印目标 Java 进程的线程堆栈信息。