United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-6731726 jmap -permstat reports only 50-60% of permgen memory usage.
JDK-6731726 : jmap -permstat reports only 50-60% of permgen memory usage.

Details
Type:
Bug
Submit Date:
2008-07-30
Status:
Closed
Updated Date:
2011-03-08
Project Name:
JDK
Resolved Date:
2011-03-08
Component:
hotspot
OS:
generic
Sub-Component:
svc
CPU:
generic
Priority:
P4
Resolution:
Fixed
Affected Versions:
7
Fixed Versions:
hs14 (b03)

Related Reports
Backport:
Backport:

Sub Tasks

Description
###@###.### wrote:
----------------------------------------------------------------------

Hi,

I'd like to contribute this patch. I need a reviewer who is familiar
with the Hotspot Serviceability Agent.

The description of the patch is something like:

        Accounting for more memory uses associated with class metadata
        in PermGen which "jmap -permstat" misses.

In a small test, the "jmap -permstat" command reports only about
50-60% of the permgen memory usage (compared to the actual usage of
permgen based on what the "jmap" command reports). This patch will
increase the number up to 80-90%.

Here's the patch which is based on a very recent version of
http://hg.openjdk.java.net/jdk7/jdk7

--- a/agent/src/share/classes/sun/jvm/hotspot/tools/PermStat.java
+++ b/agent/src/share/classes/sun/jvm/hotspot/tools/PermStat.java
@@ -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());

-      // add ConstantPoolCache, if any
-      ConstantPoolCache cpCache = k.getConstants().getCache();
-      if (cpCache != null) {
-         size += cpCache.getObjectSize();
+      // 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());
+         }
       }

-      // 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;
    }
-----------------------------------------------------------------------------

                                    

Comments
EVALUATION

See the suggested fix in description section.
                                     
2008-07-30
EVALUATION

http://hg.openjdk.java.net/jdk7/hotspot/hotspot/rev/7f601f7c9b48
                                     
2008-08-04



Hardware and Software, Engineered to Work Together