Какая бесплатная реализация JVM имеет наилучшую обработку PermGen?
Вопрос
Я запускаю Tomcat6 в JRE6 от Sun, и при каждой паре развертываний я получаю исключение OutOfMemoryException:Постоянный ток.Я погуглил PermGen-решения и перепробовал множество исправлений.Ничего не работает.Я прочитал много хорошего о Oracle JRockit и о том, как его распределение PermGen может достигать гигабайтных размеров (сравните с Sun 128 МЛН), и хотя это не решает проблему, это позволило бы мне повторно развертывать 100 раз между исключениями PermGen по сравнению с 2 разами сейчас.
Проблема с JRockit заключается в том, что для использования его в производстве вам нужно купить WebLogic, который стоит тысячи долларов.Какие другие (бесплатные) варианты существуют, которые более щадят расширение PermGen?Как нижеприведенные JVM работают в этой области?
- IBM JVM
- Откройте JDK
- Затемнение
- Каффе
...другие?
Обновить: Некоторые люди спрашивали, почему я думал, что PermGen max равен 128M.Причина в том, что каждый раз, когда я пытаюсь поднять его выше 128 Мб, моя JVM не инициализируется:
[2009-06-18 01:39:44] [info] Error occurred during initialization of VM
[2009-06-18 01:39:44] [info] Could not reserve enough space for object heap
[2009-06-18 01:39:44] [395 javajni.c] [error] CreateJavaVM Failed
Странно, что попытка зарезервировать место для объекта завершается неудачей куча, хотя я не уверен, что это "та" куча, а не "а" куча.
Я загружаю JVM с начальной загрузкой 1024 МБ и максимальной загрузкой 1536 МБ.
Я закрою этот вопрос, поскольку на него был дан ответ, т.е."переключение бесполезно" и спросите вместо этого Почему моя Sun JVM терпит неудачу с большими настройками PermGen?
Решение
Я согласен с Майклом Боргвардтом в том, что вы можете увеличить размер PermGen, я не согласен с тем, что это в первую очередь связано с утечками памяти.Пространство PermGen агрессивно поглощается приложениями, которые интенсивно используют Отражение.Так что в принципе, если у вас есть приложение Spring / Hibernate, запущенное в Tomcat, будьте готовы сильно увеличить это пространство PermGen.
Другие советы
Что натолкнуло вас на мысль, что JVM Sun ограничена 128M PermGen?Вы можете свободно установить его с помощью параметра командной строки -XX:MaxPermSize;значение по умолчанию равно 64M.
Однако реальной причиной вашей проблемы, вероятно, является утечка памяти в вашем приложении, которая не позволяет классам собирать мусор;они могут быть очень тонкими, особенно когда задействованы загрузчики классов, поскольку все, что требуется, - это единственная ссылка на любой из классов в любом месте. Эта статья подробно описывает проблему, и этот предлагает способы исправить это.
Технически, пул памяти "PermGen" - это система Sun JVM.Другие JVM так это не называют, но все они имеют представление об одном или нескольких пулах памяти, отличных от кучи.
Но если у вас проблема с permgen в вашей Sun JVM, переход на другую JVM вряд ли что-то решит, он просто проявит себя под другим именем.
Если проблемы возникают из-за нескольких перераспределений, просто увеличьте PermGen виртуальной машины до больших значений.Некоторое время назад мы попробовали JRockit из-за этой самой проблемы, и он страдает от того же истощения при повторном использовании.Мы вернулись в SUn JVM.
Изменение JVM - это не панацея.Вы можете получить новые неожиданные проблемы (напримервидишь статья о запуске приложения под управлением 4 разных JVM).
- У вас может произойти утечка класса (напримерчерез загрузчики классов), которые в основном часто происходят при повторном развертывании.Честно говоря, я никогда не видел работающего горячего повторного развертывания на Tomcat (надеюсь увидеть однажды).
- У вас могут быть неправильные параметры JVM (напримердля Sun JDK 6 64 бит -XX:+использование переключателя PARNEWGC приводит к утечке постоянного сегмента памяти.Если вы добавите дополнительные переключатели:-XX:+useconmarksweepgc -XX:+CMSClassUnloadingEnabled-XX:+CMSPermGenSweepingEnabled ситуация будет разрешена.Забавно, но я никогда не встречал вышеупомянутой утечки с 32 битами Sun JDK 6). Ссылка к статье "Настройка сборки мусора JVM для производственных развертываний".
- Вашего блока PermGen может быть недостаточно для загрузки классов и связанной с ними информации (на самом деле, это чаще всего происходит после повторного развертывания в Tomcat, старые классы остаются в памяти, а новые загружаются)
Исходя из моего прошлого опыта, отладка такого рода утечек - один из самых сложных видов отладки, с которыми я когда-либо сталкивался.
[ОБНОВЛЕНО]
Полезная статья как устранить ссылку classloader при повторном развертывании приложения.
Я использую JRockit, и я все еще получаю ошибки PermGen, если я не увеличиваю объем памяти (через -XX:MaxPermSize).Я также не могу заставить что-либо работать, чтобы избежать этого (кроме как увеличить его).
Perm gen, вероятно, является самой простой памятью для обработки, я сомневаюсь, что между различными реализациями виртуальной машины будет большая разница.
Убедитесь, что все те конфигурации Tomcat, которые помечены как отключенные в рабочей среде, отключены в рабочей среде.
Да, некоторые фреймворки, которые действительно генерируют много классов "на лету", но они должны сами за собой убираться, и, в любом случае, вы можете уместить более нескольких классов в 128 МБ.
Серьезно, если perm gen продолжает расти, то эту утечку a следует устранить, хотя, возможно, это не ваша проблема, которую нужно исправлять.
В IBM JVM не имеет (и не было в 2009 году) permgen.Вы можете прочитать больше о его Параллельный Сборщик мусора поколений который является его GC по умолчанию для Java 7.
Я иногда запускал Eclipse IDE на IBM JVM специально, потому что с моими любимыми плагинами он часто заполнял permgen JVM в HotSpot.Конечно, вероятно, произошла утечка памяти, которую кто-то должен был устранить, но тем временем моя IDE не выходила из строя, и я не был занят экспериментами с различными настройками.