| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > 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 | ||
Пробовал, эти опции отсрочили эту проблему дня на 2-3, потом снова ошибка вылезла. |
| Автор: priam220 4.10.2011, 09:45 |
| Возможно твоему сервису просто не хватает места. Разростается куча и наезжает на область PermGen. Т.е. можно просто увеличить область кучи, хотя бы до гига (-Xms1024m -Xmx1024m), и посмотреть что произойдет. А возможно у тебя где то происходит утечка памяти, и тогда нужно дебажить. С JDK поставляется спец утилита, которая может помочь тебе в этом: jconsole.exe. |
| Автор: jk1 4.10.2011, 12:39 | ||
Perm gen memory leak часто возникает при редеплое "вгорячую". Разумеется, в production такого происходить не будет, так что и фиксить тут нечего. |
| Автор: Skynin 4.10.2011, 15:11 | ||
Общее описание причин такое: В PermGen хранятся байт-код классов (и там же кажется нативный, когда класс подпал под JIT) При этом уникальность класса обеспечивается не только именем а утрировано - контрольной суммой его байткода. То есть, если наше приложение загружает класс с таким же именем но скомпилированной с изменениями в PermGen будут лежать оба. Выгружаются они оттуда когда нет ни одного объекта класса Имя+СRC. Получить утечку поэтому просто: 0. Запускаем программу в которой есть класс А 1. Создаем объект класса А, и время его жизни до завершения приложения. 2. Загружаем измененный класс А повторяем пп 1 и 2 пока не получим OutOfMemoryError: PermGen space А получим - однозначно Еще в 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 |
Насколько я понимаю, они собираются с помощью GC? http://www.codeinstructions.com/2009/01/busting-javalangstringintern-myths.html (миф 3) Мне вот интересно, это есть в спецификации или зависит от реализации JVM? |