Как интерпретировать вывод из "jmap -permstat"?
Я пытаюсь устранить утечку permgen и хотел бы попросить вас рассказать о том, как интерпретировать вывод из jmap -permstat.
Скажем, что у меня есть отчет jmap -permstat, например:
class_loader classes bytes parent_loader alive? type
<bootstrap> 4791 25941568 null live <internal>
0x00000007203ed508 0 0 0x00000007203ed228 dead com/example/object/[email protected]
0x000000071dc17620 1 3056 0x0000000705e692a8 dead sun/reflect/[email protected]
0x000000071f26a898 0 100 null dead com/example/object/[email protected]
0x0000000721c6dba0 0 100 null dead com/example/object/[email protected]
0x000000071e36df20 0 100 null dead com/example/object/[email protected]
0x000000072157c1b8 339 2069112 0x000000072157b8d8 dead com/example/object/[email protected]
0x00000007128b7830 1 1912 0x0000000700056db8 dead sun/reflect/[email protected]
0x0000000707634360 1 3088 0x0000000700056db8 dead sun/reflect/[email protected]
Здесь, как бы я интерпретировал вышеприведенный вывод, пожалуйста, исправьте все ошибки, которые я сделал при этом.
Значения в столбце "тип" не уникальны. Мы видим несколько объектов, которые появляются три раза. Однако значение class_loader уникально для всех трех; поэтому каждый из них представляет собой отдельный объект, занимающий пространство перггенов. В этом примере каждый из них занимает 100 байт; поэтому 300 байтов пространства перменов занимают объекты типа SomeClassLoader.
Если значение классов отличное от нуля, то этот объект должен быть каким-то классом-загрузчиком, и это относится к числу классов, которые он ссылается. (Примечание: в фактическом файле эти три объекта имеют нули в столбце байтов, я добавил значения для этого примера. На практике я предполагаю, что если в столбце классов есть 0, значение байта может быть любым, кроме нуля.)
Если живое значение "мертвое", это означает, что объект готов к сбору мусора, но JVM этого не делает. Там будет отдельное обсуждение причин, почему это может быть так.
Если в столбце parent_loader есть значение, то это объект, на который ссылается другой загрузчик классов, и не может быть мусором, собранным до тех пор, пока этот объект не будет собран.
Наконец:
1) Если я вижу 500 строк в отчете, все списки одного типа,
2), но они перечисляют разные значения class_loader,
3), то я могу добавить значения в столбец байтов
4), и это будет точно представлять, сколько пространства пергменов занято объектами этого типа.
Это правильно? Спасибо!
Ответы
Ответ 1
Из этого запись в блоге:
Для каждого объекта загрузчика класса печатаются следующие данные:
- (class_loader). Адрес объекта загрузчика класса - при снимке при запуске утилиты.
- (classes) Количество загруженных классов (определяется этим загрузчиком с помощью метода (java.lang.ClassLoader.defineClass).
- (байты) Примерное количество байтов, потребляемых метаданными для всех классов, загруженных этим загрузчиком классов.
- (parent_loader). Адрес загрузчика родительского класса (если есть).
- (живой?) Индикация "живая" или "мертвая" - указывает, будет ли объект-загрузчик собирать мусор в будущем.
- (type) Имя класса этого загрузчика классов.
Постоянное поколение не содержит простые объекты, а метаданные класса (см. Что действительно означает PermGen?). Итак, переписывая ваше выражение:
Наконец: 1) Если я вижу 500 строк в отчете, что все перечисляют один и тот же тип, 2), но они перечисляют разные значения class_loader, 3), тогда я могу добавить значения в столбце 4 байт), и это будет точно укажите, сколько пространства пергменов занято мета-данными для всех классов, загружаемых объектами класса loader того же класса (SomeClassLoader).
"Сохраненная куча", показанная инструментом Eclipse Memory Analyzer, относится к памяти кучи (молодой + старой), потребляемой объектами.
Постоянное поколение находится за пределами кучи (см. fooobar.com/info/349310/...) и рассматривает метаданные класса.