Как мне узнать, что находится в постоянном поколении

#java #memory #garbage-collection #permgen #permanent-generation

Вопрос:

Учитывая кучу или работающую виртуальную машину, как мне узнать, что представляет собой содержимое постоянного поколения ? Я знаю о «jmap-permstat», но он недоступен в Windows.

Комментарии:

1. Не отвечая на ваш вопрос, но, возможно, давая ответ на вашу проблему — у Sun JVM есть permgen, но есть другие JVM, которые не страдают от этого.

2. Проблема здесь в том, что permgen (или эквивалент в других JVM) не отображается интерфейсом JVMTI, и поэтому инструменты не имеют средств для его самоанализа. Это серьезная проблема с поставщиками инструментов.

3. пожалуйста, укажите версию java. в более ранних СП sun gc был придирчив к сбору классов. кроме того, если вы получите кучу, вы можете догадаться, являются ли интернированные строки вашей проблемой.

Ответ №1:

В этой статье Мониторинг памяти с помощью Java SE 5 описывается, как программно находить информацию об использовании кучи, пулах памяти (включая пространство permgen) и так далее. Это очень просто:

     MemoryUsage usage = ManagementFactory.getMemoryMXBean().getNonHeapMemoryUsage();
    long nonHeapFree = usage.getMax() - usage.getUsed();
    long nonHeapTotal = usage.getMax();
 

В моем тестировании на OSX (Sun VM) «использование памяти без кучи» близко соответствует значениям, возвращенным для пула permgen, и, по-видимому, сделает что-то полезное на виртуальных машинах, в которых нет permgen.

Ответ №2:

Постоянное поколение содержит объект класса. Поэтому вам следует проверить дамп кучи или другую форму списка объектов для классов. Если у вас есть проблемы с размером постоянного поколения, как правило, это вызвано двумя причинами:

  • ваша программа или библиотека, которую вы используете, создает классы динамически, а размер постоянной генерации по умолчанию слишком мал — просто увеличьте размер с помощью-XX:MaxPermSize=256 м
  • ваша программа или библиотека, которую вы используете, динамически создает новые классы при каждом вызове, поэтому размер постоянной генерации непрерывно увеличивается-это ошибка программирования, которую вы должны исправить (или найти исправление/создать отчет об ошибке).

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

И хороший обзор о постоянном поколении:

http://blogs.oracle.com/jonthecollector/entry/presenting_the_permanent_generation

Комментарии:

1. Этот ответ неполон: в настоящее время у нас есть приложение, в котором происходит утечка памяти permgen, и количество загруженных классов абсолютно постоянно. Оба факта можно увидеть с помощью JConsole. Мы страдаем от той же проблемы, что и оригинальный плакат, в том, что у нас нет возможности подробно проанализировать пермген.

Ответ №3:

Смотрите мой пост в блоге о размере затмения

Короче говоря, анализатор памяти может это сделать, но вам нужна SAP JVM.

Ответ №4:

У вас есть конкретная проблема, которую нужно решить? Использование String.intern() является одной из типичных причин проблем с permgen. Кроме того, у проектов с большим количеством классов также есть проблемы с пермгеном.

Я не знаю, как попасть в пермген и посмотреть, что там такое…

Ответ №5:

Постоянное поколение на самом деле содержит только два вида вещей: определения классов и интернированные строки. Последнее очень редко доставляет вам проблемы, но его часто обвиняют в проблемах. Чаще всего первое вызывает проблемы из-за генерации кода и частичной горячей перезагрузки (висячие ссылки).

В отличие от названия, permgen в конечном итоге тоже проходит GC’ed, просто не является частью регулярного цикла GC. Следовательно, неиспользуемые интернированные строки и неиспользуемые классы действительно очищаются. Но permgen также не растет динамически, что означает, что иногда необходимо вручную изменять его настройки для запуска JVM.

Ответ №6:

Я изучаю то же самое, но из-за ограничений памяти встроенной платформы.

Посмотрите на код для jmap, инструмент permstat доступен только в том случае, если sun.jvm.hotspot.tools.Доступен класс HeapSummary. Этот класс является частью агента работоспособности. Согласно документации OpenJDK (http://openjdk.java.net/groups/serviceability/svcjdk.html#bsa):

Компоненты агента обслуживания создаются как часть стандартной сборки репозитория HotSpot. Эти компоненты являются:

-libsaproc.so: это компонент собственного кода SA.

-sa-jdi.jar: Это содержит классы Java SA. Он включает в себя реализацию JDI, которая позволяет клиентам JDI выполнять отладку только для чтения основных файлов и зависших процессов.

SA используется jinfo, jmap, jstack

ПРИМЕЧАНИЕ. Агент работоспособности и технологии, которые его используют, в настоящее время не включены в выпуски JDK на платформах Windows.

Похоже, что это относится и к Oracle JDK. Я хочу изменить инструмент jmap, чтобы получить больше информации.

Ответ №7:

Один из методов, который помог мне, состоял в том, чтобы использовать -verbose:class опцию командной строки для java, и вы получите вывод журнала, сообщающий вам, как загружаются/выгружаются классы. Поскольку классы загружаются в permgen, это может помочь в определенных обстоятельствах.

Ответ №8:

вы можете использовать JConsole или jvisualvm.exe(с jdk 1.6 7), чтобы найти, что где находится. Если вы хотите знать, как все ваши объекты связаны друг с другом и с деревом объектов, то вы можете попробовать анализатор памяти Eclipse — http://www.eclipse.org/mat/.

Таким образом, вы получите то, что хотите от «http://www.eclipse.org/mat/«.

Удачи,

Комментарии:

1. Я специально ищу, какие объекты находятся в постоянном поколении. Эти инструменты не ответят на этот вопрос.

2. Привет, Том, МЭТ может ответить на ваш вопрос, но вам придется использовать SAP JVM, который, к сожалению, в данный момент немного сложно получить. Вам нужно будет получить NW CE от sdn.sap.com/irj/sdn/nw-ce