gpt4 book ai didi

java - 从 Drool 的工作内存中删除事实后堆大小没有减少

转载 作者:行者123 更新时间:2023-11-29 03:28:07 27 4
gpt4 key购买 nike

我正在创建并插入相当轻量级的 Person 对象,这些对象在 Drool 的工作内存中有一个字段 - age。但即使在删除事实后,堆大小也没有减少。示例代码-(使用来自 maven 的 Drools 6.0.0.CR5)

    long numOfFacts=1000000;

long heapSize = Runtime.getRuntime().totalMemory();
System.out.println("Heapsize before insertion: "+heapSize);

System.out.println("Inserting objects");
ArrayList<FactHandle> factHandles = new ArrayList<FactHandle>(100);
for (int i = 0; i < numOfFacts; i++) {
Person person = new Person();
person.setAge(randomGenerator.nextInt(100));
FactHandle factHandle = wkmem.insert(person);
factHandles.add(factHandle);

}

long heapSizeAfter = Runtime.getRuntime().totalMemory();
System.out.println("Heapsize after insertion: "+heapSizeAfter);


long endTimeInsert = System.currentTimeMillis();
long elTime= endTimeInsert-startTimeInsert;
System.out.println("Time it took to insert " +numOfFacts+" objects :"+elTime+" milliseconds");

long startTime = System.currentTimeMillis();
System.out.println("Number of facts: " + wkmem.getFactCount());

wkmem.fireAllRules();
long stopTime = System.currentTimeMillis();
long elapsedTime = stopTime - startTime;
System.out.println("Time it took for evaluation: " + elapsedTime);
for(int i=0;i<numOfFacts;i++){
wkmem.retract(factHandles.get(i));
}

long heapSizeAfterRemoval = Runtime.getRuntime().totalMemory();
System.out.println("Heapsize after removal of facts: "+heapSizeAfterRemoval);

代码的输出是-

Heapsize before insertion: 158138368
Inserting objects
Heapsize after insertion: 746717184
Time it took to insert 1000000 objects :5372 milliseconds
Number of facts: 1000000
Time it took for evaluation: 839
Heapsize after removal of facts: 792002560

为什么堆大小实际上增加了?

最佳答案

如 Peter Lawrey 的回答中所述,您不会在方法执行过程中看到堆大小减小。除非 GC 恰好在那一刻开始。要对此进行测试,您需要有一个长时间运行的应用程序并使用诸如 JConsole 之类的东西连接到它或使用某种分析器。

但是值得注意的是,你的回缩方式并不靠谱,在某些情况下会导致内存泄漏。事实上,在某些情况下,Drools 会在内部生成 FactHandles,因此在撤回与您自己的事实句柄引用相关联的所有事实之后,工作内存中可能还有更多内容。如果我没记错的话,这些会保留对您的事实的引用,从而防止这些对象被垃圾收集。因此,收回所有事实句柄要安全得多:

public void retractAll() {
for (FactHandle handle : ksession.getFactHandles()) {
retract(handle);
}
}

... 或收回过滤器的所有 FactHandles:

public void retractAll(ObjectFilter filter) {
for (FactHandle handle : ksession.getFactHandles(filter)) {
retract(handle);
}
}

我很难发现这一点……我的撤回代码最初做出了与您相同的假设。 :)

关于java - 从 Drool 的工作内存中删除事实后堆大小没有减少,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19898226/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com