2015-04-15 2 views
0

Я пытаюсь отладить приложение, которое висит. Программа использует очередь, реализованную с LinkedList, и во время стресс-тестирования я обнаружил, что программа перестает отвечать из-за нехватки памяти кучи. Я проанализировал дамп кучи и обнаружил, что память, похоже, протекает с LinkedList.LinkedList Memory Leak

Соответствующая часть дампа кучи:

▶java.net.Vectior @ 0xff5eacd0 
▶▶java.util.Vector @ 0xff629f30 
▶▶▶java.lang.Object[1280] @ 0xff629f50 
▶▶▶▶class com.itnade.vsm.staticobject.TrapQueue @ 0xff6b23e8 
▶▶▶▶▶java.util.LinkedList @ 0xff6b2460 
▶▶▶▶▶▶java.util.LinkedList$Node @ 0xfb954560 
▶▶▶▶▶▶java.util.LinkedList$Node @ 0xfb959968 
▶▶▶▶▶▶java.util.LinkedList$Node @ 0xfb95ede8 
▶▶▶▶▶▶java.util.LinkedList$Node @ 0xfb964230 
▶▶▶▶▶▶java.util.LinkedList$Node @ 0xfb969638 
... 
... 

Как вы можете видеть из дампа, то LinkedList$Node s не удаляются, а накапливаются.

Общий поток программы:

            Queue.offer() → → Queue.poll Queue.remove (объект)

Почему LinkedList по всей видимости, утечка памяти и как я могу предотвратить это?

+0

Пожалуйста, предоставьте соответствующий код для репликации проблемы и более подробной информации об окружающей среде: какая версия Java, какая ОС, аргументы, используемые для выполнения Java-приложения, и ... –

ответ

1

согласно How to handle memory Leaks while continuous insertion in a LinkedList?:

Ваша проблема не будет решена явно удаление объектов ... в основном потому, что нет никакого способа, чтобы сделать это в Java.

«Если вы действительно создаете слишком много мусора для коллекционера CMS, чтобы справиться с ним, то единственным решением является использование пула объектов для переустановки объектов буфера вместо того, чтобы бросать их на пол для GC. Тем не менее, вы должны быть осторожны, что вы не заменить текущую проблему с другими:

The recycled objects may need to be "cleaned" (zeroed). 
A poorly designed object pool can be a memory leak. 
A poorly designed object pool can be a concurrency bottleneck. 
A poorly designed object pool can increase GC overheads, especially if you are running with a heap that is too small. 

С другой стороны, ваша реальная проблема может быть, что ваша куча слишком мала для приложения, которое вы пытаетесь запустить , Если вы заходите слишком близко к пределу, GC не будет возвращать много мусора каждый раз. Поскольку стоимость запуска GC пропорциональна количеству NON-мусора, легко видеть, что эффективность GC является нелинейной, так как куча становится ближе к полной ».

вы можете вызвать сборщик мусора в точке кода следующим кодом: 'system.GC();'

+0

Будьте очень осторожны, полагаясь на 'System. gc() ': http://stackoverflow.com/questions/2414105/why-is-it-bad-practice-to-call-system-gc –

+0

Вы никогда не должны называть' System.gc() '... когда-либо ... это вызывает серьезный GC, который обычно должен происходить очень редко. Это очень дорого, и обычно (всегда, я всегда на 90% уверен, но не уверен, что все алгоритмы) - событие «стоп-мир». Если вы когда-либо называете это, это означает, что вы пытаетесь очистить всю кучу, и вы ожидаете больших задержек в пропускной способности – searchengine27