Почему растет пространство PermGen? - PullRequest
17 голосов
/ 12 января 2010

Я прочитал несколько статей и понял следующее (пожалуйста, исправьте меня и / или отредактируйте вопрос, если я не прав):

Куча Java сегментирована следующим образом:

  • Молодое поколение: сюда создаются объекты, эта часть часто и недорого собирается мусором

  • Старое поколение: сюда попадают объекты, которые выживают в сборках мусора поколения Юнга, эта область собирается мусором реже и использует более ресурсоемкий процесс / алгоритм (я думаю, это называется mark-sweep)

Редактировать: как указано другим пользователем, PermGen не является частью региона под названием heap

  • PermGen: эта область заполнена метаданными классов вашего приложения и многими другими вещами, которые не зависят от использования приложения.

Итак, зная это ... почему мое пространство PermGen увеличивается, когда приложение находится под большой нагрузкой? То, что я сказал ранее, не должно постепенно заполнять это пространство, несмотря на загрузку приложения, но, как я уже говорил в начале, возможно, я ошибаюсь в некоторых предположениях.

На самом деле, если пространство PermGen растет, есть ли способ сбора мусора или сброса его?

Ответы [ 7 ]

19 голосов
/ 12 января 2010

На самом деле, в JVM от Sun постоянное поколение (PermGen) полностью отделено от кучи. Вы уверены, что не смотрите на поколение постоянных? Было бы действительно подозрительно, если бы ваше постоянное поколение продолжало расти.

Если ваша численность населения постоянно растет, это сложная область для изучения. Как правило, он должен расти, когда новые классы загружаются в первый раз (и это может также вызвать определенное использование отражения). Срочные строки также хранятся в perm gen.

Если вы оказались в Solaris, вы можете использовать jmap -permstat для выгрузки постоянной статистики, но эта опция недоступна в Windows (и, возможно, на других платформах). Вот документация по jmap для Java 6

Из руководства Sun по JConsole (которое позволит вам просмотреть размер этих пулов):

Для Java HotSpot VM, память бассейны для серийного сбора мусора являются следующие.

  • Eden Space (куча): пул, из которого изначально выделена память для большинства объектов.
  • Survivor Space (куча): Пул, содержащий объекты, которые выжили сборка мусора Эдема пространство.
  • Tenured Generation (куча): пул, содержащий объекты, которые существовали какое-то время в космосе выживших.
  • Постоянное поколение (без кучи): пул, содержащий все отражающие данные самой виртуальной машины, такие как объекты класса и метода. С Виртуальные машины Java, использующие класс обмена данными, это поколение делится на области только для чтения и чтения-записи.
  • Кэш кода (без кучи): Java VM HotSpot также включает в себя кэш кода, содержащий память, которая используется для компиляция и хранение нативных Код.
6 голосов
/ 12 января 2010

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

http://frankkieviet.blogspot.com/2006/10/how-to-fix-dreaded-permgen-space.html

http://frankkieviet.blogspot.com/2006/10/classloader-leaks-dreaded-permgen-space.html

6 голосов
/ 12 января 2010

Наиболее распространенные причины, которые я видел:

  • Пользовательские загрузчики классов, которые не освобождают более старые классы после загрузки новых.
  • Классы, оставшиеся в PermGen после повторного развертывания приложения (чаще встречается в Dev, чем в Prod)
  • Интенсивное использование прокси-классов, которые создаются синтетически во время выполнения. Легко создавать новые прокси-классы, когда одно определение класса может быть повторно использовано для нескольких экземпляров.
2 голосов
/ 12 августа 2011

Если вы работаете с приложением Java EE, это, вероятно, утечка загрузчика классов.

вам могут пригодиться следующие дополнительные ссылки:

http://www.zeroturnaround.com/blog/rjc201/

http://www.ibm.com/developerworks/java/library/j-dclp3/index.html

2 голосов
/ 12 января 2010

Вы делаете что-то интересное с цепочкой загрузчиков? Вы звоните intern() на кучу строк?

0 голосов
/ 20 апреля 2013

Наиболее распространенные причины, которые я видел:

  1. загружены классы Java
  2. JAXBContext.newInstance
  3. String.intern ()
0 голосов
/ 12 января 2010

Это очень распространенная проблема, когда вы манипулируете загрузчиком классов. Это часто встречается в приложениях Java EE при повторном развертывании hibernate / cglib. Для получения дополнительной информации проверьте

http://opensource.atlassian.com/confluence/spring/display/DISC/Memory+leak+-+classloader+won%27t+let+go

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...