#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