一: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占用了太多的内存,剩下的就只需要定位到代码排查原因即可