Процесс java утекает из кучи памяти
У меня есть java-процесс, который создает в них кратковременный поток и короткий прямой байтовый буфер в них непрерывно каждые 10 миллисекунд, который съедает системную память. Хотя байтовые буферы недолговечны, они не очищаются. Я вызвал проблему и добавил maxDirectMemorySize, а такжеmaxCacheBufferSize
тоже, хотя по-прежнему демонстрирует такое же поведение. Это из-заmaxCacheBufferSize
? Я имею в виду, что каждый поток выделяет прямую память, эквивалентнуюmaxCacheBufferSize
?
-XX:MaxDirectMemorySize=256M
-Djdk.nio.maxCachedBufferSize=262144
while(true) {
for (int i=0; i<100; i++) {
es.execute(() -> {
try {
ByteBuffer buffer = ByteBuffer.allocateDirect(2048);
Thread.sleep(10);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
});
}
1 ответ
В куче Java прямой байтовый буфер - это очень маленький объект, который просто имеет указатель на собственный массив...
Когда куча Java заполнится, сборщик мусора очистит эти небольшие объекты, а когда эти небольшие объекты будут очищены, собственные массивы будут освобождены...
Но для заполнения кучи Java требуется МНОГО этих очень маленьких объектов. Если объем памяти, который вы используете в куче Java, невелик по сравнению с объемом, который вы используете в системной куче, то эти собственные массивы могут оставаться в течение длительного времени и поглощать много системной памяти.
Вам просто не следует иметь кучу недолговечных буферов с прямым распределением. Вероятно, вам следует просто использовать буферы, выделенные в куче, или повторно использовать буферы, выделенные напрямую, чтобы их можно было повторно использовать вместо выделения новых.