对于系统的活跃度比较高,承受的访问压力也很大的系统会出现比较严重的问题,可能一个是内存占用高,一个是还有一些未知bug。由于这些问题而想到我们这两个系统是否有内存泄露?是否可以用某种方法来检测内存泄露?当然经过google后,答案是肯定的。所以我们用测试环境来做一个实验,来验证检测方法的可行性。下面就是详细的整个过程。
解决问题
一些概念
1、什么是JRockit?
Oracle JRockit JVM 是业界性能最高的 Java 虚拟机,现已内置于 Oracle 融合中间件中。它通过 JRockit Real Time 提供业内领先的实时基础架构功能,通过 JRockit Mission Control 提供无与伦比的 JVM 诊断。
以上是摘自官方的。其实它等同于sun的jdk,但是它多提供了一个JRockit Mission Control来对jvm的性能和内存泄露进行检测。详情可参照这里
第一步:下载
到这里,然后点下载链接。选中上面的"接受许可协议"后方可下载。由于我们用的JBoss版本是4.2.1GA,是比较老的应用服务器,所以我们这边选择下载的也是sun jdk1.5相对应的版本[Oracle JRockit Real Time 3.1.2 适用于 Java 版本 5.0]的那一列,中选择linux-64位版本,文件名jrrt-3.1.2-1.5.0-linux-x64.bin。下载完后,拷贝到服务器上。
第二步:安装
以root身份登录到服务器,在下载文件的目录执行./jrrt-3.1.2-1.5.0-linux-x64.bin。然后选择安装目录时候请键入/usr/ali/jrrt-3.1.2-1.5.0也是我们要安装的位置。然后按提示选择。请不要安装的/root/或者/usr/root/目录下,那样会产生权限问题而不能运行。一步一步到最后,提示安装成功位置。安装中的提示都是很简单的,仔细查看酌情选择选项即可。并新建一个link到安装位置,执行如下命令 ln -s /usr/ali/jrrt-3.1.2-1.5.0 jrockit。
第三步:配置
1、首先将环境变量JAVA_HOME指向新建的link位置/usr/ali/jrockit。
执行如下命令:vi /etc/profile
打开profile文件,查找JAVA_HOME指向,将其改为/usr/ali/jrockit,保存并退出。
为了让这个更改立马生效我们执行 source /etc/profile 命令。
2、此时请切换到admin登录账号,更改JBoss启动脚本,以这次diablo为例修改的是/home/admin/shinkansen/bin/jbossctl
找到
JAVA_OPTS="-server -Xms512m -Xmx1024m -XX:NewSize=256m -XX:MaxNewSize=256m -XX:PermSize=96m -XX:MaxPermSize=96m"
在这行后面加上这样一行参数:
JAVA_OPTS="$JAVA_OPTS -verbosegc -Dcom.sun.management.jmxremote.port=端口号 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Djava.rmi.server.hostname=服务器ip"
请自己指定端口号,这个端口是供Oracle JRockit Mission Control 来诊断jvm的,默认为7091。
服务器ip请指定为当前服务器ip。
第四步:启动JBoss
请在admin账号登录下,执行/home/admin/shinkansen/bin/jbossctl restart重启动JBoss。随后请检查启动是否正常。
注意如果不能停止JBoss请执行ps aux|grep java 找到 shinkansen那个进程,用 kill -9 进程号 强杀掉
第五步:开始诊断
下载Oracle JRockit Mission Control 3.1.2
到这里,然后点下载链接。选中上面的"接受许可协议"后方可下载。版本[Oracle JRockit Mission Control 3.1.2 适用于 Java 版本 5.0]的那一列,中选择Windows x86位版本。在本机安装。
安装完成后打开主界面如图:
然后右键见左边栏的连接器,中选择新建连接,出现新建连接窗口。
随后出现了一个新的链接,点中它,右键选启动memleak。
选中一个内存占用比较高的类型,然后右键点跟踪堆栈,如下图。
这样我们就可以从堆栈中追踪到我们的类。