Drools规则运行后未从内存删除引发内存泄漏,求可行解决方案
Drools规则引擎加载规则后内存泄漏问题
业务场景
某模块使用Drools业务规则引擎,每个数据集对应一套从Excel文件加载的规则,通过Spring Batch作业运行。
问题描述
每运行一次批处理作业,Drools加载的规则都不会从内存中清除,最终引发内存泄漏,该问题已通过YourKit分析器确认。
核心代码
读取规则、创建KieContainer实现
private static KieFileSystem getKieFileSystem(String rulesFileName,String tenant,String filePath) throws Exception { log.debug("inside getKieFileSystem method."); log.debug("tenant is:: " + tenant + ", file name is:: " + rulesFileName); //TO-DO decide whether base path will come from base.properties of framework or //if it will be read from application.properties of this project log.debug("filePath:: " + filePath); log.debug("final filepath ::: " + filePath + tenant + "/" + rulesFileName); KieFileSystem kieFileSystem = kieServices.newKieFileSystem(); kieFileSystem.write(ResourceFactory.newFileResource(filePath+tenant+"//"+rulesFileName+"")); log.debug("end of getKieFileSystem method."); return kieFileSystem; } public static KieContainer getKieContainer(String rulesFileName, String tenant, String filePath) throws Exception { log.debug("inside getKieContainer method."); log.debug("Create container..."); getKieRepository(); KieBuilder kb = kieServices.newKieBuilder(getKieFileSystem(rulesFileName,tenant,filePath)); kb.buildAll(); KieModule kieModule = kb.getKieModule(); KieContainer kContainer = kieServices.newKieContainer(kieModule.getReleaseId()); log.debug("... Container created!"); log.debug("end of getKieContainer method."); return kContainer; }
已尝试的清理操作
批处理作业运行完成后执行以下清理逻辑,无法释放规则占用的内存:
// 1. 删除KieFileSystem中的规则文件 KieFileSystem.delete(filePath+tenant+"//"+rulesFileName+""); // 2. 从KieRepository移除KieModule kieServices.getRepository().removeModule(kContainer.getReleaseId());
修复建议
- 补充KieContainer显式销毁逻辑:在移除KieModule之前,先调用
kContainer.dispose()方法释放容器本身持有的所有资源,包括规则会话、编译后的规则类引用,这是当前清理逻辑缺失的核心步骤。 - 检查静态引用:
getKieContainer为静态方法,确认没有静态集合缓存KieContainer、KieBase、KieSession实例,避免强引用导致GC无法回收相关资源。 - 补充Drools版本适配的清理逻辑:如果使用Drools 7.x及以上版本,移除KieModule后可额外调用
kieServices.getRepository().dispose()释放仓库缓存,注意如果是全局共用KieServices实例,仅确认无其他业务使用时执行该操作。 - Spring Batch场景优化:相同租户+相同规则文件的KieContainer做复用,仅当规则文件变更时才重建实例并销毁旧容器,从根源减少重复创建带来的内存开销。
- 内存泄漏定位补充:通过YourKit确认占内存的对象如果是
org.drools.core.definitions.impl.KnowledgePackageImpl或者编译生成的规则类实例,需额外检查所有业务创建的KieSession是否都调用了dispose()方法释放会话资源。
内容的提问来源于stack exchange,提问作者Suhas_United
相关产品推荐
相关产品推荐

