I'm trying to troubleshoot a permgen leak, and wanted to ask you folks for your opinions on how to interpret the output from jmap -permstat.
Let's say that I have a jmap -permstat report, like this:
class_loader classes bytes parent_loader alive? type
<bootstrap> 4791 25941568 null live <internal>
0x00000007203ed508 0 0 0x00000007203ed228 dead com/example/object/SomeObjectType$FirstClassLoader@0x0000000something1
0x000000071dc17620 1 3056 0x0000000705e692a8 dead sun/reflect/DelegatingClassLoader@0x0000000something4
0x000000071f26a898 0 100 null dead com/example/object/SomeClassLoader@0x0000000something3
0x0000000721c6dba0 0 100 null dead com/example/object/SomeClassLoader@0x0000000something3
0x000000071e36df20 0 100 null dead com/example/object/SomeClassLoader@0x0000000something3
0x000000072157c1b8 339 2069112 0x000000072157b8d8 dead com/example/object/SomeObjectType$SecondClassLoader@0x0000000something2
0x00000007128b7830 1 1912 0x0000000700056db8 dead sun/reflect/DelegatingClassLoader@0x0000000something4
0x0000000707634360 1 3088 0x0000000700056db8 dead sun/reflect/DelegatingClassLoader@0x0000000something4
Here's how I would interpret the above output-- please correct any mistakes that I've made in doing so.
The values in the "type" column aren't unique. We see some objects that appear three times. However, the class_loader value is unique across all three; therefore, each of them is a distinct object, occupying permgen space. In this example, each one occupies 100 bytes; therefore, 300 bytes of permgen space are being occupied by objects of type SomeClassLoader.
If the classes value is non-zero, then this object must be a class loader of some kind, and this refers to the number of classes it references. (Note: In the actual file, those three objects have zeroes in the bytes column; I've added values for this example. In actual practice, I'm guessing that if there is a 0 in the classes column, there's no way the bytes value can be anything but zero.)
If the alive value is "dead", that means that the object is ready to be garbage-collected, but the JVM is not doing so. There's a separate discussion to be had as to reasons why this might be the case.
If there is a value in the parent_loader column, then this is an object that is referenced by another class loader, and cannot be garbage collected until that object is garbage collected.
Finally: 1) If I see 500 lines on the report that all list the same type, 2) but they list different class_loader values, 3) then I can add up the values in the bytes column 4) and this will accurately represent how much permgen space is being occupied by objects of that type.
Is this correct? Thanks!
From this blog entry:
For each class loader object, the following details are printed:
- (class_loader) The address of the class loader object – at the snapshot when the utility was run.
- (classes) The number of classes loaded (defined by this loader with the method(java.lang.ClassLoader.defineClass).
- (bytes) The approximate number of bytes consumed by meta-data for all classes loaded by this class loader.
- (parent_loader) The address of the parent class loader (if any).
- (alive?) A “live” or “dead” indication – indicates whether the loader object will be garbage collected in the future.
- (type) The class name of this class loader.
Permanent generation doesn't contain plain objects but class meta-data (See What does PermGen actually stand for?). So, rewriting your statement:
Finally: 1) If I see 500 lines on the report that all list the same type, 2) but they list different class_loader values, 3) then I can add up the values in the bytes column 4) and this will accurately represent how much permgen space is being occupied by meta-data for all classes loaded by class loader objects of the same (SomeClassLoader) class.
"Retained Heap" shown by Eclipse Memory Analyzer tool is referring to heap memory (young + old) consumed by objects.
Permanent generation is outside of the heap (See https://stackoverflow.com/a/12058171/33622) and deals with class metadata.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With