Когда и как Java classloader отмечен для сборки "мусора"?

Мы создаем несколько дочерний classloaders для загрузки в нескольких подприложениях в JAVA-приложение "контейнера", моделируя горячее развертывание. Когда путь к классу конкретного classloader изменился (т.е. банки были добавлены, удалены, обновлены), старый classloader выброшен (не имеющий ссылки), и новый classloader создается для нового пути к классу банок.

После обновления пути к классу, инициировав горячее развертывание, мы взяли дамп "кучи". Дамп "кучи" (использующий Память Анализатор) указывает, что старые classloaders не собирались "мусор". Определенные классы в родителе classloader кэшировали старый classloaders. Следующие вещи были вызваны для очистки этих кэшей:

java.lang.ResourceBundle.clearCache(classLoader);
org.apache.commons.logging.LogFactory.release(classLoader);
java.beans.Introspector.flushCaches();

Даже после очистки вышеупомянутых кэшей, старые classloader все еще не собирались "мусор". Остающиеся ссылки на classloader включали следующее:

  • классы загружаются classloader
  • java.lang. Пакет создал самим classloader
  • java.lang. ProtectionDomain, созданный самим classloader

Все вышеупомянутое является циклическими ссылками в classloader, который должен инициировать сборку "мусора". Я не уверен, почему это не. Кто-либо знает, почему старые classloaders все еще не собираются "мусор" даже с циклическими ссылками?

43
задан Neeme Praks 17 April 2013 в 09:38
поделиться

1 ответ

Я всегда слышал, что выгрузка Classloader была проблематичной. Они теоретически собирают мусор, когда нет ссылки на экземпляры объекта и выгрузка классов не требуется, но на практике это кажется более проблематичным. Незначительные ссылки могут привести к утечке и предотвратить восстановление загрузчика классов . На серверах приложений после многочисленных циклов повторного развертывания я иногда получал OutOfMemoryError: PermGen space .

Все это для того, чтобы сказать, что я предполагаю, что где-то есть неприятная ссылка, которая препятствует ее сбору - возможно, анализатор памяти неправильно перешел по ссылке. Похоже, что все это может произойти, как описано в этих статьях:

Кроме того, я точно не знаю, что вы делает, но если вы можете дождаться JDK 7, вы можете взглянуть на AnonymousClassLoader . Они будут представлены для лучшей поддержки динамического языка, как объясняется в этом посте:

Я надеюсь, что это поможет вам.

17
ответ дан 26 November 2019 в 23:11
поделиться
Другие вопросы по тегам:

Похожие вопросы: