1

Drool の作業メモリに1 つのフィールドを持つかなり軽量Personのオブジェクトを作成して挿入しています。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

ヒープサイズが実際に増加したのはなぜですか?

4

2 に答える 2

3

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);
    }
}

私はこれを難しい方法で発見しました...私の撤回コードは、最初にあなたと同じ仮定をしました。:)

于 2013-11-11T09:27:04.180 に答える