I've taken a the jmap -permstat
output of a JVM (reported as version 24.76-b04), it reports the following totals:
total = 5190 76930 1031431696 N/A alive=1, dead=5189 N/A
Which should be the number of entries, classes using this information, bytes used for metadata and liveness information.
Now, I wonder why it would report 1031431696 bytes
, just shy of a Gigabyte when I startup my VM with -XX:MaxPermSize=256m
. Can someone shed light on how the number is calculated?
Don't know if it's relevant but this is using Rhino with ~3k entries being DefiningClassLoader
s.
I have looked a bit at the code for the jmap -permstat
implementation. The bytes used value is an estimation based on sizes for the different types of data a classloader loads (methods, fields, interfaces etc).
The top level method that does the size calculation for a loaded class is sun.jvm.hotspot.tools.PermStat.computeSize
:
private long computeSize(InstanceKlass k) {
long size = 0L;
// the InstanceKlass object itself
size += k.getObjectSize();
// Constant pool
ConstantPool cp = k.getConstants();
size += cp.getObjectSize();
size += objectSize(cp.getCache());
size += objectSize(cp.getTags());
// Interfaces
size += arraySize(k.getLocalInterfaces());
size += arraySize(k.getTransitiveInterfaces());
// Inner classes
size += objectSize(k.getInnerClasses());
// Fields
size += objectSize(k.getFields());
// Methods
ObjArray methods = k.getMethods();
int nmethods = (int) methods.getLength();
if (nmethods != 0L) {
size += methods.getObjectSize();
for (int i = 0; i < nmethods; ++i) {
Method m = (Method) methods.getObjAt(i);
size += m.getObjectSize();
size += objectSize(m.getConstMethod());
}
}
// MethodOrdering - an int array that records the original
// ordering of methods in the class file
size += arraySize(k.getMethodOrdering());
return size;
}
My guess is that this estimation fails horribly in your case. The reason it fails is hard to say without checking the object size calculations in detail for your JVM version in combination with the characteristics of the loaded classes in your application.
Also, the Troubleshooting Guide for Java SE 6 with HotSpot VM mentions that the value is an approximation.
Bottom line, take the bytes used value with a grain of salt.