Объекты не завершаются, а поток Finalizer ничего не делает

На нашем сервере у нас начались проблемы с OutOfMemoryError. Мы проанализировали дампы кучи с помощью Eclipse Memory Analysis и обнаружили, что многие объекты удерживались для финализации (около 2/3 кучи):

введите здесь описание изображения

Мы обнаружили, что это может быть какая-то блокировка метода finalize(). Я нашел несколько отчетов об ошибках, связанных с этой проблемой (здесь или здесь), и это всегда проявлялось в стеке потоков Finalizer. , что его где-то заблокировали. Но в нашем случае этот поток ЖДАЛ:

"Finalizer" daemon prio=10 tid=0x43e1e000 nid=0x3ff in Object.wait() [0x43dfe000]
   java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        - waiting on <0x4fe053e8> (a java.lang.ref.ReferenceQueue$Lock)
        at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:133)
        - locked <0x4fe053e8> (a java.lang.ref.ReferenceQueue$Lock)
        at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:149)
        at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:189)

ИЗМЕНИТЬ:

Затем мы попытались добавить -XX:+UseConcMarkSweepGC, но безуспешно, уменьшилась только частота OutOfMemoryError, так что сначала мы подумали, что это помогло.

Наконец, мы заподозрили баг JVM и обновились с OpenJDK 1.6.0_30 до Oracle JDK 1.7.0_51, и проблема исчезла (по крайней мере, так кажется, за последние 4 часа используемая куча не растет). Мы не помним никаких изменений в методе финализации, и мы не обновляли никакую библиотеку, за это время были лишь незначительные изменения. Проблема не воспроизводится на нашем тестовом сервере с той же конфигурацией, за исключением того, что это 64-битная JVM, а рабочий сервер — 32-битный.

Возникает вопрос: что может быть причиной того, что объекты не завершаются, а поток Finalizer ожидает следующего объекта? Правильно ли мы проанализировали дамп кучи?

Спасибо за все ответы.


person Oliv    schedule 07.03.2014    source источник
comment
Ваш Finalizer-поток ожидает завершения чего-либо (он блокируется на ReferenceQueue.remove()), что означает отсутствие объектов для финализации. Как вы пришли к выводу, что это finalize() блокировка метода? Вы активно используете finalize() в своем коде?   -  person Kayaman    schedule 07.03.2014
comment
@Kayaman Анализируя дамп кучи, смотрите картинку   -  person Oliv    schedule 10.03.2014


Ответы (2)


Мы думаем, что это связано с версией OpenJDK 1.6.0_30. После обновления до Oracle JDK 1.7.0_51 проблема исчезла. И, вероятно, оно появилось после автоматического обновления openJDK, но это мы также не можем подтвердить. Мы не смогли найти соответствующий отчет об ошибке.

person Oliv    schedule 18.03.2014

Поток Finalizer имеет низкий приоритет, поэтому он потратит много времени WAITING, а не на завершение. Из этой трассировки стека я бы не сделал вывод, что поток заблокирован; это просто передача управления другим потокам. Скорее всего, вы вводите патологическое количество объектов в очередь финализатора, и JVM просто не справляется.

К сожалению, существует слишком много возможных объяснений того, почему это поведение изменилось между версиями, чтобы определить точную причину, но вот возможное объяснение. Oracle Java 7 имеет новый, более эффективный сборщик мусора< /а>. Разумно предположить, что уменьшение нагрузки на сборщик мусора означает, что очередь финализатора получает больше времени на процессоре и, следовательно, может не отставать от количества добавляемых в нее объектов.

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

person dimo414    schedule 23.07.2016
comment
Вероятно, это не так, поскольку средняя загрузка ЦП на этом сервере составляет около 5%, поэтому у финализатора достаточно времени для выполнения своей работы. - person Oliv; 25.12.2016