Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java EE (J2EE) и Spring > Проблема PermGen space


Автор: fenix666 1.10.2011, 09:40
Занимаюсь разработкой веб-сервисов, которые вертятся на IBM WebSphere.
В последнее время стала возникать ошибка java.lang.OutOfMemoryError: PermGen space, результате чего сфера перестает отвечать.
При этом ява запущена с опциями: -Xms256m -Xmx512m -XX:MaxPermSize=256m
Обычно память разрастается во время очередного деплоя сервиса, но также и во время работы понемногу съедается.

Есть ли способ получить содержимое этой памяти, чтобы увидеть какие классы загружены и занимают место?
Либо иной способ, побороть ее? 

Автор: Farmazon 1.10.2011, 10:34
1. при запуске жабы можно этот пермген увеличить (опция -XX:MaxPermSize при запуске)
2. При переразвёртывании бинов/вебсервисов/проч. тащить за собой меньше классов. Т.е. надо основные зависимости скинуть в папку lib, и не переразвёртывать их каждый раз.

Автор: Skynin 1.10.2011, 12:48
Попробовать добавить еще:

-XX:+CMSClassUnloadingEnabled
-XX:+CMSPermGenSweepingEnabled 

Автор: fenix666 4.10.2011, 07:37
Цитата(Skynin @ 1.10.2011,  12:48)
Попробовать добавить еще:

-XX:+CMSClassUnloadingEnabled
-XX:+CMSPermGenSweepingEnabled

Пробовал, эти опции отсрочили эту проблему дня на 2-3, потом снова ошибка вылезла.

Автор: priam220 4.10.2011, 09:45
Возможно твоему сервису просто не хватает места. Разростается куча и наезжает на область PermGen. Т.е. можно просто увеличить область кучи, хотя бы до гига (-Xms1024m -Xmx1024m), и посмотреть что произойдет. 
А возможно  у тебя где то происходит утечка памяти, и тогда нужно дебажить. С JDK поставляется спец утилита, которая может помочь тебе в этом: jconsole.exe.

Автор: LSD 4.10.2011, 10:40
Цитата(fenix666 @  4.10.2011,  08:37 Найти цитируемый пост)
эти опции отсрочили эту проблему дня на 2-3, потом снова ошибка вылезла

PermGen space в основном используется для хранения скомпилированных классов. Что у тебя за приложение такое, что постоянно подгружает новые классы?

Добавлено через 24 секунды
Возможно стоит форкнуть часть приложения?

Автор: jk1 4.10.2011, 12:39
Цитата

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

Perm gen memory leak часто возникает при редеплое "вгорячую". Разумеется, в production такого происходить не будет, так что и фиксить тут нечего.

Автор: Skynin 4.10.2011, 15:11
Цитата

Пробовал, эти опции отсрочили эту проблему дня на 2-3, потом снова ошибка вылезла.

Общее описание причин такое:
В PermGen хранятся байт-код классов (и там же кажется нативный, когда класс подпал под JIT)
При этом уникальность класса обеспечивается не только именем а утрировано - контрольной суммой его байткода.
То есть, если наше приложение загружает класс с таким же именем но скомпилированной с изменениями в PermGen будут лежать оба.
Выгружаются они оттуда когда нет ни одного объекта класса Имя+СRC.
Получить утечку поэтому просто:
0. Запускаем программу в которой есть класс А
1. Создаем объект класса А, и время его жизни до завершения приложения.
2. Загружаем измененный класс А
повторяем пп 1 и 2 пока не получим OutOfMemoryError: PermGen space

А получим - однозначно smile

Еще в PermGen хранятся intern строки. То есть те что зашиты в коде String sss = "Hello world" и те что заброшены туда с помощью String.intern() Второе делают для увеличения быстродействия, можно будет сравнивать потом по == без equals.
Если появляются все новые строки при работе программы, и мы их String.intern(), то тоже жди OutOfMemoryError: PermGen space

На практике же происходит то что jk1 описал.
или ищите, кто держит объекты перезагружаемых классов (искать можно дооолго, и самое печальное, избавиться не перелопатив архитектуру может и не получится)

P.S.
Да, а держателем класса кажется нередко выступает очередной объект ClassLoader'a. То есть будет зависеть еще от способа загрузки измененных классов в работающее приложение.

Автор: Stolzen 5.10.2011, 13:42
Цитата(Skynin @  4.10.2011,  16:11 Найти цитируемый пост)
Еще в PermGen хранятся intern строки.

Насколько я понимаю, они собираются с помощью GC? http://www.codeinstructions.com/2009/01/busting-javalangstringintern-myths.html (миф 3)

Мне вот интересно, это есть в спецификации или зависит от реализации JVM?

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)