drools內存泄露問題排查分析

[b]一、現象[/b]
某系統使用了drools規則引擎對用戶數據按照規則進行計算,在對其某查詢接口連續100W次調用過程中發現JVM內存可用量持續下降,從系統啓動時的1.5G下降爲20-30M,導致java.lang.OutOfMemoryError: Java heap space只能被迫重啓系統。
[b]二、排查[/b]
根據問題現象初步判定爲系統出現內存泄露,但系統中使用了衆多變量,如何判斷是哪些變量沒有被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,內存佔用量如下圖:

[img]http://dl.iteye.com/upload/attachment/180038/17554fde-2e3b-3f1b-82e0-74f7212901f4.jpg[/img]

google一下,[url]http://hi.baidu.com/funshare/blog/item/d2f4a8c3006c545db219a84c.html[/url]。
於是按照上面的解決方案修改drools規則計算部分代碼。
修改後第926次調用時jprofiler監控結果如下圖:
[img]http://dl.iteye.com/upload/attachment/179792/63a89e3b-529a-366a-83aa-cda2b764c783.jpg[/img]
已經沒有drools大量佔用內存情況出現了。初步確定了問題原因。
其實jconsole也是一個很好的監控工具,並且由jdk自帶。這次使用jconsole對遠程服務器上的應用進行監控。
drools計算規則代碼修改前3小時時間段內堆內存佔用量如下圖:
[img]http://dl.iteye.com/upload/attachment/179795/7efcbc1d-7800-3cd2-8cdf-39f5f9609a47.jpg[/img]
內存佔用量呈持續上升趨勢。
修改後3小時時間段內堆內存佔用量如下圖:
[img]http://dl.iteye.com/upload/attachment/179799/cdd82f4b-a7f7-38c6-8ea4-2f675d44daa9.jpg[/img]
可以看到內存佔用量比較平穩。堆內存總佔用量也有所下降。問題可以得到確認。
[b]三、經驗[/b]
通過解決該問題獲得了一些經驗教訓:
1、此類問題需要通過工具長時間的持續跟蹤才能發現,1小時內通常不容易發現問題。
2、擅用google。

------------------------------------
GC回收機制的概念和原理:[url]http://rdc.taobao.com/blog/qa/?p=4708[/url]
JVM監控工具:[url]http://androider.iteye.com/blog/293814[/url]
JProfiler和Eclipse整合:[url]http://hi.baidu.com/dburu/blog/item/c397b644e3fde78ab3b7dc78.html[/url]
Jconsole使用:[url]http://rdc.taobao.com/blog/qa/?p=1261[/url]
JConsole使用手冊:[url]http://hi.baidu.com/xuwanbest/blog/item/3f6d4c7b375ff4f10bd18731.html[/url]
利用JProfiler對應用服務器內存泄漏問題診斷一例:[url]http://yufeimen.iteye.com/blog/70721[/url]


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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章