2010-12-30 2 views
53

Этот вопрос для тех, кто когда-либо испытанной кнопку «Найти утечки» в менеджере Tomcat и получил некоторые результаты, как это:Есть ли способ избежать утечек памяти для развертывания в Tomcat?

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

Я предполагаю, что это что-то делать с этим «Пермь Gen пространства» часто возникает ошибка с частыми перераспределениями.

Так что я вижу в jconsole при развертывании, так это то, что мои загруженные классы идут от примерно 2k до 5k. Тогда вы думаете, что undeployment должно отбросить их обратно до 2k, но они останутся на уровне 5k.

Я также попытался использовать следующие параметры виртуальной машины Java:

-XX:+CMSClassUnloadingEnabled -XX:+UseConcMarkSweepGC -XX:+CMSPermGenSweepingEnabled

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

Итак, есть способ настроить Tomcat или разработать приложение для более быстрого разгрузки при развертывании? Или мы застряли в перезагрузке сервера после некоторых крупных сеансов отладки?

Tomcat версии выход:

версия сервера: Apache Tomcat/6.0.29
Сервер постройки: 19 июля 2010 1458
Номер сервера: 6.0.0.29
Название ОС: Windows 7
OS Версия: 6.1
Архитектура: x86
JVM версии: 1.6.0_18-b07
JVM Производитель: Sun Microsystems Inc.

Update:

Благодаря ответ celias' Я решил сделать немного больше рытья, и я думаю, что я определил виновного в моих приложений благодаря CXF, Spring и JAXB.

После того, как я узнал, как профилировать приложение Java, я указал профилировщик Tomcat и взял кучи дампов и снимки кучи, чтобы увидеть, как выглядели объекты и классы в памяти. Я обнаружил, что некоторые из перечислений из моей XML-схемы, используемой в моих сгенерированных классах CXF/JAXB (wsdl2java), сохранялись после развертывания. Согласно моему дампу кучи, похоже, что объекты были привязаны к карте. Отказ от ответственности: я признаю, что я все еще немного зеленый с профилированием, и отслеживание дерева вызовов объекта может быть сложным в Java.

Также следует упомянуть, что я даже не вызывал сервис, просто развернутый, а затем не развернутый. Кажется, что сами объекты загружались через отражение, инициированное Spring при развертывании. Я считаю, что я последовал за соглашением о создании службы CXF весной. Поэтому я не уверен на 100%, если это Spring/CXF, JAXB или ошибка отражения.

В качестве побочного примечания: рассматриваемая заявка представляет собой веб-сервис с использованием Spring/CXF, а XML - довольно сложная схема (расширение NIEM).

ответ

15

Если вы хотите, чтобы убедиться, что не вызывает утечки, вы должны сделать следующее:

  • Убедитесь, что веб-приложение не использует какие-либо классы Java, которые находятся в веб-контейнер разделяемых библиотек. Если у вас есть общие библиотеки, убедитесь, что нет строгих ссылок на объекты в этих библиотеках.
  • Избегайте использования статических переменных, особенно для таких объектов Java, как HashTable, Sets и т. Д. Если вам нужно, убедитесь, что вы вызываете remove освободить объекты с карты, списки ...

Здесь также хорошая статья на ThreadLocal и MemoryLeaks - http://blog.arendsen.net/index.php/2005/02/22/threadlocals-and-memory-leaks-revisited/

+0

хорошая информация! Я пробовал сделать очень простое приложение без каких-либо сторонних или общих библиотек и не видел тех же симптомов, о которых я говорил выше. Единственная проблема заключается в том, что приложение «реального мира», вероятно, будет иметь некоторые утечки памяти где-нибудь с использованием сторонних библиотек. Поэтому я думаю, все это сводится к разработчикам где-то вдоль линии. Я уверен, что мы все можем сделать улучшения: Tomcat, наши приложения, библиотеки ... – waltwood

+1

Кто-нибудь знает больше о влиянии генерации динамического байтового кода, поскольку он используется многими XML-сериализаторами, Hibernate, Tapestry? Правильно ли эти библиотеки выгружаются? – Codo

+0

Хорошо, я поспешил сказать, что я не видел таких же симптомов. Возможно, мое тестовое приложение было слишком маленьким, чтобы заметить. Я тестировал приложение Tomcat Examples, и снова увидел, что PermGen заполняется, и загруженные классы никогда не возвращались к исходному уровню после undeployment. Я понимаю, что PermGen используется для хранения метаданных об загруженных классах. Поэтому я думаю, что undeployment должно заставить Tomcat отказаться от ссылок на класс для приложения, и GC должен очистить их и их метаданные правильно? Даже если мои классы содержат сильные ссылки на другие классы, не должны ли они умереть, когда Tomcat выгружает родительские классы? – waltwood

6

Tomcat 7 должен принести улучшения в этой области. См. Features of Apache Tomcat 7, раздел под названием Нет больше утечек!

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

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

Смежные вопросы