# HG changeset patch # User martin # Date 1217555437 25200 # Node ID 7f601f7c9b48381fc9d060344a8aac1ae4c4185a # Parent c7e8144ef65e360bc5914b3bf55487848175d455 6731726: jmap -permstat reports only 50-60% of permgen memory usage. Reviewed-by: swamyv, martin Contributed-by: yamauchi@google.com diff -r c7e8144ef65e -r 7f601f7c9b48 agent/src/share/classes/sun/jvm/hotspot/tools/PermStat.java --- a/agent/src/share/classes/sun/jvm/hotspot/tools/PermStat.java Wed Jul 30 14:41:55 2008 -0700 +++ b/agent/src/share/classes/sun/jvm/hotspot/tools/PermStat.java Thu Jul 31 18:50:37 2008 -0700 @@ -266,45 +266,51 @@ out.println(); } + private static long objectSize(Oop oop) { + return oop == null ? 0L : oop.getObjectSize(); + } + + // Don't count the shared empty arrays + private static long arraySize(Array arr) { + return arr.getLength() != 0L ? arr.getObjectSize() : 0L; + } + private long computeSize(InstanceKlass k) { long size = 0L; - // InstanceKlass object size + // the InstanceKlass object itself size += k.getObjectSize(); - // add ConstantPool size - size += k.getConstants().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()); - // add ConstantPoolCache, if any - ConstantPoolCache cpCache = k.getConstants().getCache(); - if (cpCache != null) { - size += cpCache.getObjectSize(); + // 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()); + } } - // add interfaces size - ObjArray interfaces = k.getLocalInterfaces(); - size += (interfaces.getLength() != 0L)? interfaces.getObjectSize() : 0L; - ObjArray transitiveInterfaces = k.getTransitiveInterfaces(); - size += (transitiveInterfaces.getLength() != 0L)? transitiveInterfaces.getObjectSize() : 0L; - - // add inner classes size - TypeArray innerClasses = k.getInnerClasses(); - size += innerClasses.getObjectSize(); - - // add fields size - size += k.getFields().getObjectSize(); - - // add methods size - ObjArray methods = k.getMethods(); - size += (methods.getLength() != 0L)? methods.getObjectSize() : 0L; - TypeArray methodOrdering = k.getMethodOrdering(); - size += (methodOrdering.getLength() != 0L)? methodOrdering.getObjectSize() : 0; - - // add each method's size - int numMethods = (int) methods.getLength(); - for (int i = 0; i < numMethods; i++) { - Method m = (Method) methods.getObjAt(i); - size += m.getObjectSize(); - } + // MethodOrdering - an int array that records the original + // ordering of methods in the class file + size += arraySize(k.getMethodOrdering()); return size; }