使用jmap排查java程序内存泄露
1.使用jmap命令生成内存快照文件(Heap Profile)
jmap -dump:format=b,file=heap.hprof ${pid}
如果生成快照的时候遇到如下报错
Dumping heap to /mnt/tmp/heap.hprof ... Exception in thread "main" java.io.IOException: Premature EOF at sun.tools.attach.HotSpotVirtualMachine.readInt(HotSpotVirtualMachine.java:292) at sun.tools.attach.LinuxVirtualMachine.execute(LinuxVirtualMachine.java:200) at sun.tools.attach.HotSpotVirtualMachine.executeCommand(HotSpotVirtualMachine.java:261) at sun.tools.attach.HotSpotVirtualMachine.dumpHeap(HotSpotVirtualMachine.java:224) at sun.tools.jmap.JMap.dump(JMap.java:247) at sun.tools.jmap.JMap.main(JMap.java:142)
添加如下参数就可以解决
jmap -J-d64 -dump:format=b,file=/mnt/tmp/heap.hprof ${pid}
2.使用Eclipse Memory Analyzer工具对hprof文件进行分析
如果机器的java版本是java8的话,需要注意MAT 1.12.0版本需要jdk11,所以下载1.10.0版本
http://www.eclipse.org/downloads/download.php?file=/mat/1.10.0/rcp/MemoryAnalyzer-1.10.0.20200225-linux.gtk.x86_64.zip
否则会出现如下报错
Unrecognized option: --add-exports=java.base/jdk.internal.org.objectweb.asm=ALL-UNNAMED Error: Could not create the Java Virtual Machine. Error: A fatal exception has occurred. Program will exit. Unable to init server: Could not connect: Connection refused
由于堆栈快照文件可能会很大,所以需要修改 MemoryAnalyzer.ini 文件中的-Xmx1024m,比如改成-Xmx10240m,否则可能会遇到下面报错
an internal error occurred during parsing heap dump from
3.分析堆栈文件
将快照文件从服务器上下载到本地,用MAT软件来分析hprof文件
查看内存泄露报告
发现有2处可疑的泄露
点击details,排查到可能是 class io.lettuce.core.AbstractRedisClient @ 0x41bc37380 引起的
排查使用的redis依赖是否有内存泄露的可能,找到
springboot使用redis压力测试出现内存泄漏解决方案
如果堆栈快照文件很大,不方便从服务器上下载到本地的话,可以直接在服务器上进行分析,再将分析的结果下载下来进行查看,分析的结果会以zip包形式生成,生成路径和hprof文件相同,如下
将zip文件下载下来,解压查看网页,就可以看到堆栈的分析报告,如下
本文只发表于博客园和tonglin0325的博客,作者:tonglin0325,转载请注明原文链接:https://www.cnblogs.com/tonglin0325/p/5285347.html