RFR: 8044107 Add Diagnostic Command to list all ClassLoaders

Staffan Larsen staffan.larsen at oracle.com
Fri May 30 09:40:54 UTC 2014


On 30 maj 2014, at 10:49, Mikael Gerdin <mikael.gerdin at oracle.com> wrote:

> Hi Staffan,
> 
> On Wednesday 28 May 2014 16.50.28 Staffan Larsen wrote:
>> This change adds a new Diagnostic Command to list all ClassLoaders and some
>> statistics for each classloader. The command is called
>> “GC.classloader_stats” and the information listed is:
>> 
>> * An id for the ClassLoader. This is the pointer to the Klass of the
>> ClassLoader. The reason for using the Klass* (instead of the oop) is that
>> it is stable across invocations. * The id of the ClassLoader’s parent
>> ClassLoader.
>> * The pointer to the ClassLoaderData structure in the VM. This can be useful
>> for debugging. * The number of classes loaded by the ClassLoader.
>> * The total size of all allocated metaspace chunks for the ClassLoader.
>> * The total size of all allocated metaspace blocks for the ClassLoader.
>> 
>> If there are anonymous classes (invokedynamic classes) attributed to the
>> ClassLoader, the following additional information is listed: * The number
>> of anonymous classes loaded by the ClassLoader.
>> * The total size of all allocated metaspace chunks for anonymous classes in
>> the ClassLoader. * The total size of all allocated metaspace blocks for
>> anonymous classes in the ClassLoader.
>> 
>> The information is gathered during a safe point to guarantee that the data
>> structures are consistent.
>> 
>> I have added a small test and have run this through jprt. A CCC request has
>> been filed.
>> 
>> webrev: http://cr.openjdk.java.net/~sla/8044107/webrev.00/
>> bug: https://bugs.openjdk.java.net/browse/JDK-8044107
> 
> I'm going to leave the naming of the anonymous classes and dig into the code a 
> bit:
> 
> in classLoaderStats.hpp:
> 
> Use the (at runtime) known object alignment?
> 105     return hash ^ (hash >> 3); // just in case we're dealing with aligned 
> ptrs

I just copied code from resourceHash.hpp… What would you suggest?

> 
> The &-operator is not needed here:
> 108   typedef ResourceHashtable<oop, ClassLoaderStats*,
> 109       &ClassLoaderStatsClosure::oop_hash, 
> &ClassLoaderStatsClosure::oop_equals> StatsTable;

Removed.

> do_entry does not need to be virtual since the template instantiation binds to 
> the symbol during compilation
> 129   virtual bool do_entry(oop const& key, ClassLoaderStats* const& cls);

I want to override it in a closed source class, so I’ll keep it as virtual.

> in classLoaderStats.cpp:
> 
> Every time you encounter a CLD which reports a ClassLoader oop you will 
> overwrite the _cld field of the ClassLoaderStats.
>  59   cls->_cld = cld;
> 
> I'm not sure if this was your intention or not, but you are relying on the 
> subtle fact that since CLD:s are prepended to the linked list in CLDG the _cld 
> field will end up pointing to the ClassLoader's CLD instead of any of the 
> anonymous classes which also hash to the same ClassLoder oop but have 
> different CLDs. 

Good catch. The code should be:

  if (!cld->is_anonymous()) {
    cls->_cld = cld;
  }

> Can you convert this to an if()-block or add parenthesis for clarity?
>  60   cls->_classloader = cl == NULL ? NULL : cl->klass();

Added parenthesis.

> 
> The ResourceMark here is unnecessary, all the resource allocations done by the 
> ClassLoaderStats-classes are done by the VMThread and are in the scope of a 
> ResourceMark covering the call to VM_Operation::doit()
> 165   ResourceMark rm;

I wasn’t aware that doit() was already covered. Removed.

> in ClassLoaderStatsTest.java:
> There is at least one other variant of "DummyClassLoader" in the testlibrary, 
> can you see if any of them are reusable?

I could not find one that did what I wanted. Which one are you referring to?

I also changed the name of the diagnostic command from “GC.classloader_stats” to “VM.classloader_stats” and the output of anonymous classes to "+ unsafe anonymous classes”.

new webrev: http://cr.openjdk.java.net/~sla/8044107/webrev.01/

Thanks,
/Staffan


> 
> /Mikael
> 
>> 
>> Example output:
>> 
>> ClassLoader         Parent              CLData*            Classes   ChunkSz
>>  BlockSz  Type 0x00000007c002d908  0x0000000000000000  0x0000000000000000 
>>     0         0         0  sun.misc.Launcher$ExtClassLoader
>> 0x0000000000000000  0x0000000000000000  0x00007fb239c08de0     761  
>> 4694016   4241312  <boot classloader> 37     75776     50928   +
>> invokedynamic classes 0x00000007c0061028  0x00000007c0036878 
>> 0x00007fb239c2de60       1      6144      1976 
>> ClassLoaderStatsTest$DummyClassLoader 1      2048      1288   +
>> invokedynamic classes 0x00000007c0036878  0x00000007c002d908 
>> 0x00007fb239e10fc0       8     88064     31544 
>> sun.misc.Launcher$AppClassLoader Total = 4                                 
>>                    808   4866048   4327048 ChunkSz: Total size of all
>> allocated metaspace chunks
>> BlockSz: Total size of all allocated metaspace blocks (each chunk has
>> several blocks)
>> 
>> 
>> Thanks,
>> /Staffan



More information about the hotspot-dev mailing list