drools规则引擎因为内存泄露导致的内存溢出

测试环境上的数据量有370万左右,生产环境上的数据量有350万,从数据量上来看,生产环境并没有测试环境的数据量大,为什么测试环境就没有出现OOM而生产环境就OOM了呢?

带着这种疑问,我们首先加大了生产环境机器的内存,并调大了jvm内存相关参数,发现还是OOM

最后,经过种种排查,包括构造数据,使用jprofiler工具,分析dump文件,最终定位到是drools规则引擎导致的问题!

原因:

修改之前的代码:

    w.insert(user);  
    w.fireAllRules();  
    w.dispose();  

修改之后的代码:

    FactHandle fact =  w.insert(user);  
    w.fireAllRules();  
    w.dispose();  
    w.retract(fact);  

或:

    w.insert(user);  
    w.fireAllRules();  
    w.dispose();  
    w.retract(w.getFactHandle(user));  

如上代码所示,w.insert(user)执行完这句代码后会返回一个FactHandle对象,需要WorkingMemory调用retract方法将其从内存中清除掉,不然,即使走完了规则变成了垃圾对象,也无法被垃圾回收器回收,因为WorkingMemory还在引用这个插进去的User对象 。

为什么数据量大的测试环境没有出现oom呢?原因很简单:因为测试环境的数据量虽然大,但能够匹配规则的数据量少,也就是说插入进WorkingMemory中的User对象少,而生产环境正好相反,这就是为什么数据量小反倒还出现oom的原因!

结论:这是因为drools内存泄露导致的内存溢出!

网上关于drools内存泄露方面的资料还是很少的,特此记录,希望能够帮助遇到同样问题的朋友!

关于Zeno Chen

本人涉及的领域较多,杂而不精 程序设计语言: Perl, Java, PHP, Python; 数据库系统: MySQL,Oracle; 偶尔做做电路板的开发,主攻STM32单片机
此条目发表在Java分类目录。将固定链接加入收藏夹。