drools内存泄露问题排查分析

    一、现象
    某系统使用了drools规则引擎对用户数据按照规则进行计算,在对其某查询接口连续100W次调用过程中发现JVM内存可用量持续下降,从系统启动时的1.5G下降为20-30M,导致java.lang.OutOfMemoryError: Java heap space只能被迫重启系统。
    二、排查
    根据问题现象初步判定为系统出现内存泄露,但系统中使用了众多变量,如何判断是哪些变量没有被GC及时回收而导致内存泄露的呢?接下来开始寻找JVM内存监控工具。jprofiler是一个不错的选择(不过是收费软件)。找到crack,最初试图在RedHat Enterprise Linux AS release4上安装但是失败。不过可以在本地eclipse上安装jprofiler插件对内存变量进行监控分析。启动本地系统后(-Xms512M -Xmx512M),jprofiler同时启动。对本地服务连续进行10W次调用同时通过jprofiler对变量进行监控发现drools规则引擎中的部分变量占用内存量排名靠前(org.drools.*),通过jprofiler的GC强制回收功能也无法释放内存占用量,内存创建大量实例。当调用数为926次时报java.lang.OutOfMemoryError: Java heap space,内存占用量如下图:

drools内存泄露问题排查分析_第1张图片

google一下, http://hi.baidu.com/funshare/blog/item/d2f4a8c3006c545db219a84c.html
于是按照上面的解决方案修改drools规则计算部分代码。
修改后第926次调用时jprofiler监控结果如下图:
drools内存泄露问题排查分析_第2张图片
已经没有drools大量占用内存情况出现了。初步确定了问题原因。
其实jconsole也是一个很好的监控工具,并且由jdk自带。这次使用jconsole对远程服务器上的应用进行监控。
drools计算规则代码修改前3小时时间段内堆内存占用量如下图:
drools内存泄露问题排查分析_第3张图片
内存占用量呈持续上升趋势。
修改后3小时时间段内堆内存占用量如下图:
drools内存泄露问题排查分析_第4张图片
可以看到内存占用量比较平稳。堆内存总占用量也有所下降。问题可以得到确认。
    三、经验
    通过解决该问题获得了一些经验教训:
    1、此类问题需要通过工具长时间的持续跟踪才能发现,1小时内通常不容易发现问题。
    2、擅用google。

------------------------------------
GC回收机制的概念和原理: http://rdc.taobao.com/blog/qa/?p=4708
JVM监控工具: http://androider.iteye.com/blog/293814
JProfiler和Eclipse整合: http://hi.baidu.com/dburu/blog/item/c397b644e3fde78ab3b7dc78.html
Jconsole使用: http://rdc.taobao.com/blog/qa/?p=1261
JConsole使用手册: http://hi.baidu.com/xuwanbest/blog/item/3f6d4c7b375ff4f10bd18731.html
利用JProfiler对应用服务器内存泄漏问题诊断一例: http://yufeimen.iteye.com/blog/70721


vi /home/admin/test-run/bin/jbossctl.sh
JAVA_OPTS="$JAVA_OPTS -Dprogram.name=$PROGNAME -Dcom.sun.management.jmxremote.port=9999 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false"

bash jbossctl.sh stop
bash jbossctl.sh start -b10.253.67.32

你可能感兴趣的:(eclipse,jvm,linux,Blog,bash)