JDK-8068665 : GC.class_stats and VM.classloader_stats should use the same identifier when printing ClassLoaders
Type:Bug
Component:hotspot
Sub-Component:svc
Affected Version:9
Priority:P3
Status:Resolved
Resolution:Not an Issue
Submitted:2015-01-08
Updated:2016-09-01
Resolved:2016-09-01
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.
GC.class_stats and VM.classloader_stats prints ClassLoader IDs in different ways - it would be useful to use the same identifier so that data can be correlated.
Comments
Closing this as not an issue.
01-09-2016
Shall we close this? It looks like the main issue here was fixed in 8159917.
22-08-2016
The reason for printing the Klass* instead of the oop is to get a value that is stable across invocations of the command so that results can be compared.
See the review discussions here: http://mail.openjdk.java.net/pipermail/hotspot-dev/2014-June/014163.html
21-06-2016
Oops, I found that in my previous log, the number 0x00007fa7c04182f0 is actually the same across the two commands. It's only that the space between "0x00007fa7c04182f0" and "a 'jdk/internal/loader/ClassLoaders$AppClassLoader'{0x00000003d249aa00}" was missing, so the number in GC.class_stats became "0x00007fa7c04182f0a", which happens to look like a valid hex number.
I filed a bug JDK-8159917 for this.
20-06-2016
The output currently looks like this:
$ jcmd $PID GC.class_stats ClassName,ClassLoader| grep MyClass
268 49 MyClass,class loader 0x00007f767c303030a 'jdk/internal/loader/ClassLoaders$AppClassLoader'{0x00000003d249ab40}
The 0x00000003d249ab40 is the oop of the AppClassLoader instance.
$ jcmd $PID VM.classloader_stats
30813:
ClassLoader Parent CLD* Classes ChunkSz BlockSz Type
0x00000007c0050648 0x0000000000000000 0x00007f767c3419b0 1 6144 664 java.lang.invoke.MethodHandles$LookupHelper$1
0x00000007c0010150 0x0000000000000000 0x00007f767c303a70 0 0 0 jdk.internal.loader.ClassLoaders$PlatformClassLoader
0x00000007c000fd18 0x00000007c0010150 0x00007f767c303030 1 6144 3224 AppClassLoader
0x0000000000000000 0x0000000000000000 0x00007f767c21b7c0 576 4587520 3630512 <boot class loader>
Total = 4 578 4599808 3634400
ChunkSz: Total size of all allocated metaspace chunks
BlockSz: Total size of all allocated metaspace blocks (each chunk has several blocks)
The 0x00000007c000fd18 is the Klass* of jdk.internal.loader.ClassLoaders$PlatformClassLoader
20-06-2016
[~sla] I don't know why VM.classloader_stats chooses to print out the Klass* instead of the oop. The Klass* is about the type of the loader, which is already covered by the Type column. If you have 2 class loader instances of the same type, the ClassLoader column will have the same value, which is kind of confusing.
How about fixing VM.classloader_stats to print out the oop instead? That way, the number printed by the ClassLoader column in VM.classloader_stats will match the trailing number in the ClassLoader column in GC.class_stats.
=====================
diff -r 13b2c7ac95a5 src/share/vm/classfile/classLoaderStats.cpp
--- a/src/share/vm/classfile/classLoaderStats.cpp Wed Jun 15 09:48:24 2016 -0400
+++ b/src/share/vm/classfile/classLoaderStats.cpp Mon Jun 20 09:56:24 2016 -0700
@@ -101,10 +101,8 @@
bool ClassLoaderStatsClosure::do_entry(oop const& key, ClassLoaderStats* const& cls) {
Klass* class_loader_klass = (cls->_class_loader == NULL ? NULL : cls->_class_loader->klass());
- Klass* parent_klass = (cls->_parent == NULL ? NULL : cls->_parent->klass());
-
_out->print(INTPTR_FORMAT " " INTPTR_FORMAT " " INTPTR_FORMAT " " UINTX_FORMAT_W(6) " " SIZE_FORMAT_W(8) " " SIZE_FORMAT_W(8) " ",
- p2i(class_loader_klass), p2i(parent_klass), p2i(cls->_cld),
+ p2i(cls->_class_loader), p2i(cls->_parent), p2i(cls->_cld),
cls->_classes_count,
cls->_chunk_sz, cls->_block_sz);
if (class_loader_klass != NULL) {
=====================
$ jcmd $PID GC.class_stats ClassName,ClassLoader| grep MyClass
267 49 MyClass,class loader 0x00007fa7c04182f0a 'jdk/internal/loader/ClassLoaders$AppClassLoader'{0x00000003d249aa00}
$ jcmd $PID VM.classloader_stats
ClassLoader Parent CLD* Classes ChunkSz BlockSz Type
0x00000003d24c3158 0x0000000000000000 0x00007fa7c047fde0 1 6144 688 java.lang.invoke.MethodHandles$LookupHelper$1
0x00000003d249a618 0x0000000000000000 0x00007fa7c0423300 0 0 0 jdk.internal.loader.ClassLoaders$PlatformClassLoader
0x00000003d249aa00 0x00000003d249a618 0x00007fa7c04182f0 1 6144 3280 jdk.internal.loader.ClassLoaders$AppClassLoader
0x0000000000000000 0x0000000000000000 0x00007fa7c025bff0 576 4587520 3717632 <boot class loader>
20-06-2016
VM.classloader_stats is added in JDK9 by JDK-8044107.
20-06-2016
GC.class_stats just prints the name of the ClassLoader. VM.classloader_stats also includes the handle to the ClassLoader's Klass instance, its parent ClassLoader's Klass instance, and the address of the ClassLoaders's ClassLoaderStats instance.