ClassLoader Leak - стоит ли их решать?
ClassLoader
Утечки обычно приводят к java.lang.OutOfMemoryError: PermGen. В случае работы на серверах приложений вы можете увидеть это в результате многочисленных повторных развертываний обычного приложения. Объяснение и возможные решения этой проблемы можно увидеть по этим двум ссылкам. (среди прочих)
http://dev.eclipse.org/blogs/memoryanalyzer/2008/05/17/the-unknown-generation-perm/ http://blogs.oracle.com/fkieviet/entry/classloader_leaks_the_dreaded_java
Теперь по большей части их легко обойти. Просто увеличьте -XX:MaxPermSize, и когда это произойдет, полностью перезапустите JVM. Проблема с попыткой решить эту проблему заключается в том, что в больших приложениях многие классы могут вызвать утечку загрузчика классов и, таким образом, классы остаются в пределах permgen.
Два вопроса возникают из этого:
Разумно ли говорить, что для такой проблемы лучше просто увеличить максимальный размер перми и перезапустить, где необходимо, или поиск решения должен быть более приоритетным?
Есть ли более простые способы устранить утечку загрузчика классов?
5 ответов
Это действительно зависит от приложения, а точнее от используемого процесса развертывания. Многие приложения переопределяются только во время разработки, новые выпуски выпускаются раз в несколько месяцев, а сервер приложений перезапускается по другим причинам гораздо чаще, чем развертывание приложения. В этих условиях погоня за утечками Classloader является пустой тратой времени.
Конечно, если вы планируете внедрить непрерывный процесс развертывания, особенно в среде высокой доступности, то утечки Classloader - это то, что вам действительно нужно устранить. Но есть много других вещей, которые нужно сделать лучше, чем большинство проектов, прежде чем это станет проблемой.
@biziclop прав. Вы должны быть прагматичными по этому поводу.
Если проблема только в тестовых серверах, вы можете, вероятно, отклонить это как не стоящее усилий для решения.
Если проблема в производственных серверах, то вам нужно решение или обходной путь. Решение - тяжелая работа, но обходные пути могут быть меньше работы:
Обходной путь № 1 - не выполняйте горячее развертывание на производственных серверах; делайте только полную передислокацию и перезапуск.
Обходной путь № 2 - периодически делайте полный перезапуск рабочих серверов, чтобы избежать исчерпания пространства permgen. Объедините это с увеличением пространства пермгена.
В хорошо обеспеченной / хорошо управляемой среде вы должны проводить все тестирование на отдельных серверах. Если время простоя полного развертывания вызывает беспокойство, вы должны минимизировать сбои повторного развертывания, используя репликацию сервера и постепенное повторное развертывание. Горячие развертывания в производство должны быть ненужными.
Если вы находитесь в ситуации, когда у вас нет условий для тестирования и вы часто выполняете горячее развертывание на производственной машине, чтобы минимизировать время простоя, вы катаетесь на тонком льду. Скорее всего, вы в конечном итоге совершите ошибку, которая приведет к повреждению, которое восстанавливается после...
Это одна из худших утечек... но любая утечка - это зло. Поэтому я лично разрешаю их. Профилирование также помогает. Простых путей как таковых нет, но:
- Потоки идут в threadGroups + начальный поток для каждого модуля, чтобы гарантировать, что новые Threads() имеют эту группу.
- Особая забота о Thread.inheritedAccessControlContext (который содержит ссылку на загрузчик классов)
- WeakReferences, когда вам нужно сохранить классы, на самом деле используйте WeakReferences для слушателей, чтобы никто не мог пропустить отмену регистрации (и использовать только annon. Clasess). Наличие основы для WeakListeners действительно помогает.
- Дополнительный уход за дисками БД, java.security.Provider
- еще несколько хитростей (в том числе динамическое улучшение файлов классов, но обычно это излишне)
Нижняя линия:
Утечки - это зло.
Да, есть более простые и правильные способы устранения утечек. Добавьте библиотеку ClassLoader Leak Prevention в свой проект, и она должна решить эту проблему для вас!
Если вы захотите отследить утечки самостоятельно, эта серия блогов поможет вам.
Я бы подошел к проблеме прагматично:
- Это вызывает проблемы в производственных условиях?
- У вас есть достаточно времени и ресурсов, чтобы выследить это?
Если ответ на оба этих вопроса - "да", то обязательно сделайте это. Если это один "да", один - "нет", то, вероятно, это зависит от руководства, чтобы решить, если оба нет, не беспокойтесь.