RFR: 8044107 Add Diagnostic Command to list all ClassLoaders
Mikael Gerdin
mikael.gerdin at oracle.com
Mon Jun 2 07:28:07 UTC 2014
On Friday 30 May 2014 11.40.54 Staffan Larsen wrote:
> 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?
oops can have a larger alignment than 3, since you know that you will always
have oops as the hash key, why not use that knowledge and shift them down the
appropriate amount?
>
> > 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.
Ok.
>
> > 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.
Thanks.
>
> > 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 was thinking about
test/testlibrary/com/oracle/java/testlibrary/ByteCodeLoader.java
or, perhaps to a lesser extent
test/runtime/testlibrary/ClassUnloadCommon.java
It just seems like creating a class loader in order to load a specific class
is something that is not entirely uncommon in our testing. If you don't see a
good opportunity for making this into a reusable component for other tests
then that's fine too.
>
> 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”.
Ok.
>
> new webrev: http://cr.openjdk.java.net/~sla/8044107/webrev.01/
Looks good.
/Mikael
>
> 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