Как анализировать содержимое PermGen?
Я хочу получить свалку PermGen, чтобы понять, почему она заполняется. Есть ли способ проанализировать это? Я уже знаю об общих подозреваемых, таких как log4j, tomcat webapp reloading и т.д., Но у меня также есть собственный код генерации прокси-сервера в моем приложении и просто хочу посмотреть под капот.
Возможно ли это как-то?
Ответы
Ответ 1
PermGen обычно состоит из пула строковых литералов и загруженных классов. Чтобы ответить на часть вашей проблемы, то есть пул строковых литералов, я написал утилиту для печати запущенного пула литералов JVM. Он доступен здесь:
https://github.com/puneetlakhina/javautils/blob/master/src/com/blogspot/sahyog/PrintStringTable.java
Он основан на PermStat, который является классом, используемым для печати параметров пергмена с помощью инструмента jmap.
Ответ 2
Вы можете использовать флаги:
-XX:+TraceClassLoading -XX:+TraceClassUnloading
Они печатают идентификаторы классов по мере их загрузки/выгрузки из постоянного поколения. Если вы добавите -XX:+PrintGCDetails
, вы также можете отслеживать размер константы.
Обратите внимание, что я не уверен, что флаги поддерживаются в JVM, отличных от Sun.
Еще один подозреваемый в ошибках памяти из-за недостатков PermGen - string interning. Проверьте места, где вы ставите строки в своем коде.
Ответ 3
Если вы хотите получить список всех загруженных классов, вы можете использовать jconsole
. Перейдите на вкладку "Классы" и нажмите "Подробный вывод". Это напечатает каждый класс, загруженный в stdout
. Я нашел это очень полезное отслеживание проблемы прокси-сервера JAXB.
Возможно, вам придется запустить приложение с параметром командной строки -Dcom.sun.management.jmxremote
, чтобы jconsole
подключался к нему.
Ответ 4
Будет ли jmap -permgen
соответствовать счету?
См. руководство по устранению неполадок для Java
http://java.sun.com/javase/6/webnotes/trouble/TSG-VM/html/memleaks.html#gbyuu