0

У меня есть приложение, работающее на HotSpot jvm 1.8.0_45 с хорошо упакованной кучей 8 ГБ. Приложение пытается выделить память для новых объектов с ошибкой OOM в кучном пространстве. Я посмотрел на кучу кучи и обнаружил, что большая часть пространства занята charBufferCaches экземпляров T4CConnection. Эти кэши содержат SoftReferences для массивов char. Я был удивлен, что SoftReferences не был выпущен перед OOM. Я дважды проверял, есть ли жесткие ссылки для этих массивов, но не нашел их.Ошибка OOM и странные SoftReferences

Почему у меня есть область памяти с кучей, когда приложение хранит 3 ГБ массивов символов SoftReferences? Почему это SoftReferences не выпущено, когда приложение нуждается в новой памяти?

Часть объекта T4CConnection показывая charBufferCache:

part of T4CConnection object showing charBufferCache

Входящие ссылки на массив символов holded в T4CConnection charBufferCache:

incoming references for char array holded at T4CConnection charBufferCache

+0

Когда была взята свалка? возможно, что массив был оставлен чем-то в стеке, и это не отразилось на дампе после того, как стек был размотан из-за исключения. также конкретный тип вопросов ООМ, например. превышение должно было произойти, даже если запрос на распределение мог быть выполнен после освобождения мягких ссылок. – the8472

+0

Дамп был создан с использованием опции + HeapDumpOnOutOfMemoryError JVM. Я думал, что моментальные снимки, созданные этой опцией, должны содержать все объекты и ссылки в момент появления ошибки OOM. Есть ли вероятность, что некоторые ссылки будут отсутствовать в снимке? Кроме того, мое приложение не потребляет память большими кадрами - нет никаких шансов, что он попытается сразу выделить объект 2GB. – nukie

+0

Да, я думаю, что этот параметр включает в себя корни стека. но точный тип OOME все равно может иметь значение. – the8472

ответ

1

В идеале мягкой ссылки должны быть очищены, прежде чем выбросить ООМ. Я заподозрить есть некоторая утечка памяти в программе ..

Вы можете посмотреть на здесь - How to cause soft references to be cleared in Java?

пытаются -XX:SoftRefLRUPolicyMSPerMB=<value> параметр, чтобы ограничить размер мягких ссылок и проверить, поможет ли это. Это может привести к следующему шагу.

+0

Спасибо, @Anand Vaidya! Я попробую этот вариант. – nukie

-1

SoftReference или WeakReference будут очищены только в том случае, если объект очищен. Это не помешает собирать объект, но если этот объект имеет где-то сильную ссылку, он будет сохранен после GC.

например.

Double d = new Double(123456); 
WeakReference<Double> ref = new WeakReference<>(d); 
System.gc(); 
System.out.println(ref.get() + " == " + d); // both not null. 
+0

спасибо, @Peter Lawrey! Я понимаю, что слабая/мягкая магия не будет работать, если приложение содержит сильные ссылки. Я искал входящие ссылки для каждого подозрительного объекта реферала SoftReferenece на моей дампе кучи. Я не нашел никаких ссылок на массивы тысяч char рядом с мягкими справочными контейнерами ... Это основная проблема моей проблемы: у меня есть живые мягкие ссылки на объекты и нет сильных ссылок для этих массивов ... – nukie