You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 21:57:01