JDK-6656031 : SA: jmap -permstat number of classes is off by 1
  • Type: Bug
  • Component: core-svc
  • Sub-Component: tools
  • Affected Version: 5.0u4,6,8
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2008-01-28
  • Updated: 2018-02-15
  • Resolved: 2014-01-30
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
8u162Fixed 9 b04Fixed
If you load 2 classes with custom classloader, the output of jmap -permstat shows 3 classes for this class loader:

Attaching to process ID 25522, please wait...
Debugger attached successfully.
Client compiler detected.
JVM version is 12.0-b01-fastdebug
586 intern Strings occupying 34032 bytes.
finding class loader instances ..done.
computing per loader stat ..done.
please wait.. computing liveness.................................................done.
class_loader    classes bytes   parent_loader   alive?  type

<bootstrap>     317     891720    null          live    <internal>
0xadb72d18      0       0         null          live    sun/misc/Launcher$ExtClassLoader@0xb1c97550
0xadb82248      3       3208    0xadb7b320      live    java/net/URLClassLoader@0xb1c972a8
0xadb7b320      11      74328   0xadb72d18      live    sun/misc/Launcher$AppClassLoader@0xb1ce0610

total = 4       331     969256      N/A         alive=4, dead=0     N/A

import java.net.*;
import java.io.*;

public class ClassLoading {
        public static void main(String[] args) throws Exception {
                String dir = new File(".").getCanonicalPath();
                URLClassLoader loader = new URLClassLoader(new URL[] { new URL("file://" + dir + "/a.jar") });
                Class a = loader.loadClass("A");
                Class b = loader.loadClass("B");

Affects JDK 7 and JDK 8 VM nightly. Please backport if feasible.

The analysis shows that this is caused by storing the declaring classloader (the one which is initially asked for a certain class) instead of the defining classloader (the one actually loading and defining the class) in the SystemDictionary. Both classes A and B extend java.lang.Object and there java.lang.Object needs to be loaded through the URLClassLoader. The fact that the class defined by the bootstrap classloader is used in the end is ignored and java.lang.Object is assigned to the URLClassLoader instance.

Tests now will have another name: tmtools/jmap/clstats/jmap_clstats_basic_generating_live tmtools/jmap/clstats/jmap_clstats_basic_generating_core