JVM内存泄露排查

一:tomcat配置jconsole远程连接

1. jdk配置jmxremote.password

cp jmxremote.password.template jmxremote.password

2.jmxremote.password最后增加下列内容

monitorRole  QED

controlRole   password1111


3.tomcat服务bin/catalina.sh文件增加下列内容

JAVA_OPTS="$JAVA_OPTS -Djava.rmi.server.hostname=10.10.77.145 -Dcom.sun.management.jmxremote"
JAVA_OPTS="$JAVA_OPTS -Dcom.sun.management.jmxremote.port=12345"
JAVA_OPTS="$JAVA_OPTS -Dcom.sun.management.jmxremote.authenticate=true"
JAVA_OPTS="$JAVA_OPTS -Dcom.sun.management.jmxremote.ssl=false"

JAVA_OPTS="$JAVA_OPTS -Dcom.sun.management.jmxremote.pwd.file=/home/jdk1.7.0_71/jre/lib/management/jmxremote.password"


10.10.77.145:当前tomcat服务机器的IP地址

12345:jconsole远程服务开放的端口

重启tomcat服务

二:jconsole工具远程连接

打开本地windows机器jdk安装目录bin/jconsole.exe工具



连接成功后出现下列图表



打开内存图表,我这里配置了CMS(concurrentMarkSweep)垃圾回收机制,所以显示的是CMS Old Gen,如果没配置CMS,应该是perm Old Gen(老年代区)。

当验证程序是否有内存泄露时,可以高并发的发送请求让服务程序一直在处理请求,可以看见下列的线条一直处于上升状态,当过一会儿后(时间可以长一点),点击执行GC,当内存使用率没有下降,则大致表明有内存泄露。这里可以让程序多调试几次,确定是否是由于内存泄露导致的。 如果程序无内存泄露,则正确的线条状态应如下所示。


三:jmap命令导出堆内存使用情况

jmap -heap pid       查看jvm堆内存使用情况

pid表示tomcat服务进程号,我配置了CMS垃圾回收机制,如果不配置,应该是 perm old generation,表示老年代堆区(jvm老年代区自行百度),如果是内存泄露,这里的内存会一直上升,直到100,就算调用gc,内存使用率也不会下降。



jmap -dump:format=b,file=./heap.bin pid  导出堆使用详情文件

pid表示tomcat服务进程号,为了更能排查那里出现了内存泄露,等到老年代内存使用率达到90%以上最佳,等一会就导出完成


四:MAT图形化查看堆内存使用情况

下载MemoryAnalyzer工具 http://www.eclipse.org/mat/downloads.php 点击打开链接

解压文件,打开mat目录下文件MemoryAnalyzer.exe工具


导入刚才堆内存文件heap.bin



打开详情,从上图可知类DubboFilterUtil有问题,从下图可知对象RequestInfo占用了太多的内存,剩下的就只需要定位到代码排查原因即可



你可能感兴趣的:(java)