JDK-8236968 : jmap -clstats fails to work after JDK-8232759
  • Type: Bug
  • Component: core-svc
  • Sub-Component: tools
  • Affected Version: 15
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2020-01-11
  • Updated: 2020-01-22
  • Resolved: 2020-01-15
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.
JDK 15
15 b06Fixed
Related Reports
CSR :  
Duplicate :  
Relates :  
Description
sun/tools/jmap/BasicJMapTest.java fails after JDK-8232759 due to the removal of GC.class_stats in the VM.
jmap -clstats doesn't work any more.

```
[2020-01-11T03:03:59.930482Z] Waiting for completion for process 37563
[2020-01-11T03:03:59.930565Z] Waiting for completion finished for process 37563
[/Users/fool/workspace/open/jdk/build/macosx-x86_64-server-release/images/jdk/bin/jmap, -clstats, 37553]
[2020-01-11T03:03:59.933976Z] Gathering output for process 37564
Exception in thread "main" com.sun.tools.attach.AttachOperationFailedException: java.lang.IllegalArgumentException: Unknown diagnostic command
        at jdk.attach/sun.tools.attach.VirtualMachineImpl.execute(VirtualMachineImpl.java:223)
        at jdk.attach/sun.tools.attach.HotSpotVirtualMachine.executeCommand(HotSpotVirtualMachine.java:309)
        at jdk.jcmd/sun.tools.jmap.JMap.executeCommandForPid(JMap.java:133)
        at jdk.jcmd/sun.tools.jmap.JMap.main(JMap.java:118)

[2020-01-11T03:04:00.037617Z] Waiting for completion for process 37564
[2020-01-11T03:04:00.037699Z] Waiting for completion finished for process 37564
[2020-01-11T03:04:00.037746Z] Waiting for completion for process 37564
[2020-01-11T03:04:00.037777Z] Waiting for completion finished for process 37564
STDERR:
 stdout: [];
 stderr: [Exception in thread "main" com.sun.tools.attach.AttachOperationFailedException: java.lang.IllegalArgumentException: Unknown diagnostic command
        at jdk.attach/sun.tools.attach.VirtualMachineImpl.execute(VirtualMachineImpl.java:223)
        at jdk.attach/sun.tools.attach.HotSpotVirtualMachine.executeCommand(HotSpotVirtualMachine.java:309)
        at jdk.jcmd/sun.tools.jmap.JMap.executeCommandForPid(JMap.java:133)
        at jdk.jcmd/sun.tools.jmap.JMap.main(JMap.java:118)
]
 exitValue = 1

java.lang.RuntimeException: Expected to get exit value of [0]

        at jdk.test.lib.process.OutputAnalyzer.shouldHaveExitValue(OutputAnalyzer.java:455)
        at BasicJMapTest.testClstats(BasicJMapTest.java:127)
        at BasicJMapTest.main(BasicJMapTest.java:58)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:564)
        at com.sun.javatest.regtest.agent.MainWrapper$MainThread.run(MainWrapper.java:127)
        at java.base/java.lang.Thread.run(Thread.java:832)
```
Comments
URL: https://hg.openjdk.java.net/jdk/jdk/rev/89db52d75aee User: coleenp Date: 2020-01-15 13:09:09 +0000
15-01-2020

Thanks for the history - I should have read the latest bug updates before I went and researched this myself. :) I think the biggest mystery here is how GC.class_stats was considered a suitable replacement for the SA functionality! VM.classloader_stats is much more appropriate.
14-01-2020

My theory why GC.class_stats was picked was wrong because VM.classloader_stats was added before that. changeset: 25051:8110ec6e7340 user: sla date: Wed Jun 04 11:05:30 2014 +0200 summary: 8044107: Add Diagnostic Command to list all ClassLoaders Anyone using this and understanding the output, given that the documentation doesn't match, should be able to cope with the change in output.
14-01-2020

Yes, I started a CSR to remove this but then realized when talking to Harold that VM.classloader_stats is exactly (or very similar) what jmap -clstats used to print when it used to call the SA (sorry about the formatting): $ jhsdb jmap --clstats --pid 15474 Attaching to process ID 15474, please wait... Debugger attached successfully. Server compiler detected. JVM version is 15-internal+0-2020-01-13-1355485.coleen... finding class loader instances ..done. computing per loader stat ..done. please wait.. computing liveness.............................................done. class_loader classes bytes parent_loader alive? type <bootstrap> 404 1714050 null live <internal> 0x0000000715f169b0 0 0 null live jdk/internal/loader/ClassLoaders$BootClassLoader@0x00000008002e8fa8 0x0000000715f16d10 0 0 0x0000000715f169b0 live jdk/internal/loader/ClassLoaders$PlatformClassLoader@0x000000080038a758 0x0000000715f17728 1 1111 0x0000000715f16d10 live jdk/internal/loader/ClassLoaders$AppClassLoader@0x000000080038ad30 total = 4 405 1715161 N/A alive=4, dead=0 N/A calling jcmd. $ jcmd 15474 VM.classloader_stats 15474: ClassLoader Parent CLD* Classes ChunkSz BlockSz Type 0x000000080038a758 0x0000000000000000 0x00007fd114356f70 0 0 0 jdk.internal.loader.ClassLoaders$PlatformClassLoader 0x000000080038ad30 0x000000080038a758 0x00007fd11434c570 1 6144 2632 jdk.internal.loader.ClassLoaders$AppClassLoader 0x0000000000000000 0x0000000000000000 0x00007fd11424b1c0 478 4587520 166856 <boot class loader> Total = 3 479 4593664 169488 ChunkSz: Total size of all allocated metaspace chunks BlockSz: Total size of all allocated metaspace blocks (each chunk has several blocks) So we should just change jmap tool to call this jcmd instead.
14-01-2020

The stackoverflow link was for -permstat, not -clstats. Oh, and I now see your VM.classloader_stats comment above. I missed it earlier. This looks a lot like what -permstat provided.
14-01-2020

I'd like to do that if the CSR is approved. Thanks.
14-01-2020

There's a sample in the stackoverflow link. It may have been useful to determine memory leaks in PermGen. With the JFR memory leak detector and all the other heap dump tools that we have, I don't think this should be reimplemented (unless customer specifically requests it). This jmap option should be removed. I can write a CSR for it, and [~jiefu] can provide the code.
14-01-2020

Yeah, I was thinking it was probably related to removing core dump support for jmap and other tools in JDK 9. I guess there was SA support for what -clstats (supposedly) did. I think probably it was a bug to make it use GC.class_stats. Would be interesting to look at what -clstats output looked like before the changes for JDK 9.
13-01-2020

https://stackoverflow.com/questions/13365961/how-to-interpret-the-output-from-jmap-permstat
13-01-2020

We also have this: $ jcmd 24518 VM.classloader_stats 24518: ClassLoader Parent CLD* Classes ChunkSz BlockSz Type 0x000000080038ad30 0x000000080038a758 0x00007f1dd8353ab0 1 6144 2632 jdk.internal.loader.ClassLoaders$AppClassLoader 0x000000080038a758 0x0000000000000000 0x00007f1dd834bf40 0 0 0 jdk.internal.loader.ClassLoaders$PlatformClassLoader 0x0000000000000000 0x0000000000000000 0x00007f1dd824b1b0 478 4587520 169800 <boot class loader> Total = 3 479 4593664 172432 ChunkSz: Total size of all allocated metaspace chunks BlockSz: Total size of all allocated metaspace blocks (each chunk has several blocks)
13-01-2020

Well, first off I wouldn't consider the CL hierarchy to be the same as CL stats. Also, the docs for -clstats says: "Prints class loader wise statistics of Java heap. For each class loader, its name, how active it is, address, parent class loader, and the number and size of classes it has loaded are printed." So I kind of wonder how we ever ended up with it using GC.class_stats. I found myself looking at JDK8 docs and jmap had a -permstat option: "Prints class loader wise statistics of permanent generation of Java heap. For each class loader, its name, liveness, address, parent class loader, and the number and size of classes it has loaded are printed. In addition, the number and size of interned Strings are printed." But this option is gone in 9. This sounds like what -clstats should have been doing, and better than your VM.classloaders suggestion, but then one has to wonder how things ended up like this. Between -clstats and -permstats, we have too many cases of incorrect naming, incorrect documenting, and incorrect implementing. Also for JDK8 the docs say says "jmap prints shared object memory maps or heap memory details..." and the help out says that with no options "jmap prints shared object mappings". However, now it just says "The jmap command prints details of a specified running process" and makes no mention of "shared object mappings". My guess is originally dumping "shared object mappings" is what jmap was written for, and then the heap related dumping got added later. Then we dropped "shared object mappings" support, and now we have a heap dumping tool that is called jmap when it should be called jheap or something like that.
13-01-2020

I didn't know jmap had this option when I deprecated the jcmd option, so I'll file a CSR so that we can remove it. Funny thing is that -clstats documentation looks like it should call jcmd VM.classloaders $ jmap -dump:live 17893 Usage: jmap -clstats <pid> to connect to running process and print class loader statistics jmap -finalizerinfo <pid> to connect to running process and print information on objects awaiting finalization jmap -histo[:[<histo-options>]] <pid> to connect to running process and print histogram of java object heap jmap -dump:<dump-options> <pid> to connect to running process and dump java heap jmap -? -h --help to print this help message This would be a much nicer use of this option, depending on if anyone actually uses it: $ jcmd 17893 VM.classloaders 17893: +-- <bootstrap> | +-- "platform", jdk.internal.loader.ClassLoaders$PlatformClassLoader | +-- "app", jdk.internal.loader.ClassLoaders$AppClassLoader What do you think?
13-01-2020

Shall we also remove the -clstats option for jmap? I had made a patch to remove it. But it may not be a good idea. So just re-assign it to Coleen. Thanks.
11-01-2020