Когда вызывается finalize для синглетонов при выпуске загрузчика классов? - PullRequest
5 голосов
/ 29 февраля 2012

Под "выпущенным" я подразумеваю, что нет никаких ссылок на загрузчик классов.

Мы столкнулись с проблемой, когда часто развертываемое приложение Java EE поглощает пространство permgen.Анализ показывает, что одиночный объект в приложении Java EE передал ссылки на объекты приложения-загрузчика классов за пределы приложения (в нарушение правил Java EE) и не очищает их, когда приложение не развернуто.

При условии, что не осталось никаких других ссылок на синглтон или объект класса, будет ли вызываться finalize () синглтона, когда будет освобожден загрузчик классов его класса? Я хотел бы очистить мошенникавнутренние ссылки там.Или я нахожусь в ловушке 22, где finalize не будет вызываться до тех пор, пока сам загрузчик классов не будет собран сборщиком мусора - и, следовательно, никогда не будет вызван из-за мошеннических внешних ссылок?

Возможно, здесь главный вопрос:

Будет ли объект класса собираться мусором в этом случае, когда его загрузчик классов еще не может быть? Это может зависеть отспецификация поведения загрузчика классов или может зависеть от реализации.

Ссылки (другой вид! ;-)) приветствуются, но не обязательны.

Ответы [ 2 ]

4 голосов
/ 29 февраля 2012

Класс со статической ссылкой на него будет иметь право только на сборку мусора, если загрузчик классов имеет право на GCing и других ссылок на него нет.

Класс или интерфейс могут быть выгружены тогда и только тогда, когда их определяющий загрузчик классов может быть восстановлен сборщиком мусора.

http://java.sun.com/docs/books/jls/third_edition/html/execution.html#12.7

Кроме того, у каждого класса есть ссылка на его загрузчик классов. Поэтому загрузчик классов не подходит для GCing, если есть ссылки на загруженные им классы или объекты этих классов из не коллекционных объектов.

Финализатор запускается через некоторое время после того, как объект получает право на сборку мусора, и до того, как происходит фактический сборщик мусора.

Подход к бесплатным входящим ссылкам, которые мешают GCing, в финализаторе не работает. Финализатор не будет вызываться до тех пор, пока существуют такие ссылки, поскольку они препятствуют тому, чтобы объект стал пригодным для сбора мусора. Например, вы не можете разорвать эту цепочку ссылок изнутри:

singleton instance <--- singleton class <--- class loader <--
<-- any class loaded by that class loader  <-- any object of such a class
<-- object loaded by another classloader referencing such an object or class
0 голосов
/ 29 февраля 2012

Поведение финализаторов не изменяет загрузчик классов или использование perm gen, хотя и ухудшает производительность.Объекты не могут быть собраны до тех пор, пока не будет запущен финализатор.Таким образом (упрощение путем предположения, что оно не является параллельным, и игнорирование слабого / мягкого / фантомного) выполняется GC, который определяет отсутствие активных ссылок на граф объектов, включая загрузчик классов.Финализаторы добавляются в очередь финализаторов и затем выполняются.Затем после некоторого последующего прохождения GC память может быть восстановлена.Для этого требуется полная сборка мусора, в том числе в пределах разрешенного пространства, что, как правило, нечасто и может быть отключено.

В любом случае, не используйте (с сохранением состояния) синглтоны.

...