当前位置: 首页 > 知识库问答 >
问题:

Drools 6.5.0中StatefulKnowledgeSession内存泄漏。最终的

公冶高峯
2023-03-14

我一直在尝试查找使用Drools 6.5.0的应用程序中的内存泄漏问题。最终版作为其核心组件之一。

我不确定这是否真的是一个流口水的问题。为了支持我的假设,我编写了以下规则并将其部署到Drools中。

package test
import memleak.MemoryLeak;
import event.SetupEvent;

rule "Memory Leak"
    no-loop true
    when
        $event: SetupEvent();
    then
       new MemoryLeak().leak();
end

在leak()方法中,它只创建一个200MB字节的数组。

package memleak;

import java.util.ArrayList;
import java.util.List;

public class MemoryLeak {

    private static final int _10MB = 10 * 1024 * 1024;

    public List<MemObject> leak() {
        int loop = 20;
        List<MemObject> byteArr = new ArrayList<MemObject>(loop);
        for (int i = 0; i < loop; ++i) {
            byteArr.add(new MemObject(_10MB));
        }

        return byteArr;
    }
}

class MemObject {

    private byte[] contents;

    public MemObject(int size) {
        contents = new byte[size];
    }
}

在使用SetupEvent触发规则后,我调用了KieSession的“dispose”方法。但我发现之前分配的内存没有被释放。

此外,我还尝试使用规则中的“insert”方法将字节数组插入会话。它似乎也没有被释放。

有人知道这件事吗?

提前谢谢。

史蒂文

共有1个答案

祖麻雀
2023-03-14

在您的情况下,很可能会在System.gc()之后释放内存。
您可以通过使用删除来释放有状态会话的内存

使用域对象和规则,下面是插入10K设置事件的测试。

@DroolsSession(resources = "classpath:/test.drl", log = false)
public class PlaygroundTest {

    @Rule
    public DroolsAssert drools = new DroolsAssert();

    @Test
    public void testIt() {
        for (int i = 0; i < 10_000; i++)
            drools.insertAndFire(new SetupEvent());
    }
}

我甚至没有收回SetupEvent,它们没有字段,大小非常小。测试运行约5.5分钟。显示内存泄漏。。。

200M内存分配不是cpu自由操作,在我的机器上平均需要32ms。测试正在做内存分配和垃圾回收机制...

您能否创建一个复制该问题的测试?

 类似资料:
  • 我尝试用一个大表(大约一万条记录)中的记录填充JdbcRowSet。我尝试了两个变体(参见下面的代码): 创建连接对象,使用JdbcRowSetImpl(connection)实例化,在循环中执行查询。 使用JdbcRowSetImpl(DriverManager.GetConnection(“jdbc:....”)实例化,在循环中执行查询。 第一个变体会导致内存泄漏,直到堆满为止。第二个变体没有

  • 问题内容: 我认为我的android应用正在泄漏内存。我不是绝对确定这是问题所在。 应用程序打开时经常崩溃,并且logcat尝试加载位图图像时会显示“内存不足”异常。 崩溃后,我重新打开了该应用程序,它运行正常。Logcat会显示许多“ gc”,并且JIT表会不时地向上调整大小,而不会向下调整,直到应用程序因内存不足错误而崩溃。 这听起来像是内存泄漏吗?如果是这样,我该如何定位和关闭泄漏点。 这是

  • 问题内容: 我一直在追寻内存泄漏(由“ valgrind –leak-check = yes”报告),它似乎来自ALSA。这段代码已经存在于自由世界中一段时间​​了,所以我猜这是我做错的事情。 输出看起来像这样: 并继续一些页面 这是由于我在一个项目中使用ALSA并开始看到这种巨大的泄漏……或者至少是所说泄漏的报告。 所以问题是:是我,ALSA或valgrind在这里遇到问题吗? 问题答案: ht

  • 问题内容: 我有一个长时间运行的脚本,如果让脚本运行足够长的时间,它将消耗系统上的所有内存。 在不详细介绍脚本的情况下,我有两个问题: 是否有可遵循的“最佳实践”,以防止泄漏发生? 有什么技术可以调试Python中的内存泄漏? 问题答案: 看看这篇文章:跟踪python内存泄漏 另外,请注意,垃圾收集模块实际上可以设置调试标志。看一下功能。此外,请查看Gnibbler的这段代码,以确定调用后已创建

  • 本文向大家介绍Java 内存泄漏,包括了Java 内存泄漏的使用技巧和注意事项,需要的朋友参考一下 在Java中,垃圾回收(析构函数的工作)是使用垃圾回收自动完成的。但是,如果代码中有引用它们的对象怎么办?它无法取消分配,即无法清除其内存。如果这种情况一再发生,并且创建或引用的对象根本没有被使用,它们就会变得无用。这就是所谓的内存泄漏。 如果超过了内存限制,则程序将通过抛出错误(即“ OutOfM

  • 问题内容: 我使用Informix遇到了一个奇怪的问题(具体来说,我使用的是IBM.Data.Informix命名空间,即4.10 Client SDK)。我正在使用ODBC连接到IBM Informix数据库,并且遇到内存泄漏问题。该文档相当稀疏,并且我只能使用当前安装的驱动程序/ SDK。这是我用于数据库上下文的代码: } 我已尝试处置并关闭所有可以的连接,但这似乎无济于事。我是否缺少某些东西