Утечки памяти в StatefulKnowledgeSession в Drools 6.5.0.Final - PullRequest
1 голос
/ 24 марта 2020

Я пытался найти проблему утечки памяти в моем приложении, которое использует Drools 6.5.0.Final в качестве одного из основных компонентов.

Я не уверен, действительно ли это проблема Drools. Чтобы поддержать мое предположение, я написал следующее правило и развернул его в Drools.

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

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

В методе leak () он просто создает байтовый массив размером 200 МБ.

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 для запуска правила, я вызвал метод «dispose» для KieSession. Но я обнаружил, что память, которую я выделил ранее, не была освобождена.

Кроме того, я попытался использовать метод "insert" в правиле для вставки байтового массива в сеанс. Кажется, он тоже не был освобожден.

Кто-нибудь имеет представление об этом?

Заранее спасибо.

Стивен

1 Ответ

1 голос
/ 25 марта 2020

Скорее всего, память будет освобождена после System.g c () в вашем случае.
Вы можете освободить память сеанса с сохранением состояния с помощью delete


Используя ваши доменные объекты и правило, вот тест, который вставляет 10K SetupEvent s.

@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 s, они делают нет полей, размер довольно маленький. Тест выполняется ~ 5,5 минут. Покажите мне утечку памяти ...

enter image description here

200M Выделение памяти не является свободной от процессора операцией, в среднем на моей машине это занимает 32 мс. Тест выполняет выделение памяти и сборку мусора ...

enter image description here

Не могли бы вы создать тест, который воспроизводит проблему?

...