[9] RFR (M) 8054888: Runtime: Add Diagnostic Command that prints the class hierarchy

Staffan Larsen staffan.larsen at oracle.com
Mon Feb 9 09:46:48 UTC 2015


> On 6 feb 2015, at 22:21, Karen Kinnear <karen.kinnear at oracle.com> wrote:
> 
> Chris,
> 
> So I was curious - I was thinking you would printing the hex address of the j.l.ClassLoader class rather than the cld so that if folks were to look
> at a heap dump later it might be meaningful to them. Is it unlikely that they would ever want to correlate those?
> 
> 
> On Feb 6, 2015, at 3:15 PM, Chris Plummer wrote:
> 
>> I was also thinking it might be a good idea to indicate what the hex value is, although still have figured out the best way of doing this. Maybe just a simple comment before the output. Keep in mind that eventually other DCMDS will also include the cld to help uniquiely identify classes across dcmd output. Also keep in mind your earlier suggestion:
>> 
>> java.lang.Object/0x12345600
>> |--java.io.Serializable/0x12345601
>> |--java.util.RandomAccess/0x12345602
>> |--java.lang.Iterable/0x12345603
>> | |--java.util.Collection/0x12345604
>> | | |--java.util.List/0x12345605
>> |--java.util.AbstractCollection/0x12345606
>> | |  implements java.util.Collection/0x12345604
>> | |  implements java.lang.Iterable/0x12345603
>> | |--java.util.AbstractList/0x12345607
>> | |    implements java.util.List/0x12345605
>> | | |--java.util.Arrays$ArrayList/0x12345608
>> | | |    implements java.io.Serializable/0x12345601
>> | | |    implements java.util.RandomAccess/0x12345602
>> 
>> With additions to GC.class_stats:
>> 
>> Index Super ClassLoader        ClassName
>>     1    -1 0x00000007c0034c48 java.lang.Object/0x12345600
>>     2     1 0x00000007c0034c48 java.util.List/0x12345605
>>     3    31 0x00000007c0034c48 java.util.AbstractList/0x12345607
>> 
>> And GC.class_histogram:
>> 
>>  num     #instances         #bytes  class name
>> ----------------------------------------------
>>    1:           945         117736  java.lang.Object/0x12345600
>>    2:           442          50352  java.util.List/0x12345605
>>    3:           499          25288  java.util.AbstractList/0x12345607
>> 
>> I think in your case you assumed we would create a unique identifier for each class, but then we settled on just classname + ClassLoader identifier of some sort, and the CLD* works for that. So replace your hex class ID in the above with the hex CLD*.
>> 
>> Also something Karen had said is just now starting to sink in and make sense to me:
>> 
>> |-sun.misc.Launcher$AppClassLoader/null (0xyyy)
>> |-myapp/0xyyy
>> 
>> I think the idea here is that when printing a ClassLoader subclass, you include two CLDs. The first is for the ClassLoader that loaded the class, and the second is the CLD for the ClassLoader subclass itself. Thus the above indicates that myapp was loaded by 0xyyy, which is the sun.misc.Launcher$AppClassLoader, which was loaded by the null ClassLoader. 
> I apologize - I don't remember what I said. But I am not sure we need that level of complexity. I think I was asking that one of the dcmds that gives
> information could print information like 0xabc "a sun.misc.Launcher$AppClassLoader" or "a WLS.blah.GenericClassLoader" if we don't want to include
> that everywhere. Mostly people want to know the name of the class loader. Since they don't yet have names, they want to know the type of the
> classloader. So that string "a MyClassLoader" would be more meaningful than the 0xabc - except that if they
> have 5 of those they need the uniqueness. So personally I think I was proposing the 
>   java.base, 0xA/"a MyClassLoader", iface).
> 
> But I would defer to Staffan if he suggests something else.

The mapping from “Klass of the j.l.ClassLoader” to “type of the ClassLoader” is available in the VM.classloader_stats command:

ClassLoader         Parent              CLD*               Classes   ChunkSz   BlockSz  Type
0x00000007c0038d10  0x00000007c0036240  0x00007faf7843d8f0       1      6144      1496  sun.misc.Launcher$AppClassLoader
0x00000007c0036240  0x0000000000000000  0x0000000000000000       0         0         0  sun.misc.Launcher$ExtClassLoader
0x0000000000000000  0x0000000000000000  0x00007faf7852ffd0     432   4587520   2851696  <boot class loader>
Total = 3                                                      433   4593664   2853192
ChunkSz: Total size of all allocated metaspace chunks
BlockSz: Total size of all allocated metaspace blocks (each chunk has several blocks)

I think that having the mapping in one place is enough.

/Staffan

> 
> thanks for your patience,
> Karen
>> 
>> With regard to the '/' format, keep in mind that we also need an indicator of whether or not it's an interface, and there's also a request to include the module name when that becomes available. At one point you requested the following, which is what I was aiming for:
>> 
>> java.lang.Object
>> |--java.io.Serializable (java.base, 0x00000007c00375f8, iface)
>> |--java.util.RandomAccess (java.base, 0x00000007c00375f8, iface)
>> 
>> So maybe I can do:
>> 
>> java.lang.Object
>> |--java.io.Serializable/0x00000007c00375f8 (java.base, intf)
>> |--java.util.RandomAccess/0x00000007c00375f8 (java.base, intf)
>> ...
>> |-sun.misc.Launcher$AppClassLoader/0x00000007c00375f8 (java.base, CLD=0x000000087654320)
>> |-myapp/0x000000087654320
>> 
>> So now the classname and its classloader id (which is the CLD*)  are grouped together to make it easy to strip out or to search for in more than one dcmd output. I think this is probably what you were striving when you proposed using '/', and other DCMDs can eventually be changed to do the same. Also, once you know the CLD of the ClassLoader, you can find out the name of the ClassLoader class by looking for             CLD=<classloaderID>
>> 
>> I can go with "null" for the null ClassLoader if you want. I used it's ClassLoaderData* to be consistent with the other ClassLoaders. Just let me know which you prefer.
>> 
>> thanks,
>> 
>> Chris
>> 
>> On 2/6/15 12:52 AM, Staffan Larsen wrote:
>>> I think this looks good! Perhaps we should give a hint as to what the hex value is? I don�t know if it is best to print this as part of a �header� printed before the rest of the output or if we should include it as part of each line �(classloaderdata*=0x080609c8)�.
>>> 
>>> /Staffan
>>> 
>>>> On 6 feb 2015, at 05:49, Chris Plummer <chris.plummer at oracle.com> <mailto:chris.plummer at oracle.com> wrote:
>>>> 
>>>> [Hmm. My previous email somehow included the attachment with the dcmd output, but not the body of the message, so here it is again.]
>>>> 
>>>> Hey Folks,
>>>> 
>>>> Sorry about the delay in getting the next webrev for this out. I was sidetracked by a few other things, including being out sick of almost a week, and there were also quite a few changes to make.
>>>> 
>>>> I'm ready for review with an updated webrev, but thought first I'd have you look at and comment on the output. Please see the attached file. It now supports:
>>>> 
>>>>    printing the hierarchy for a single class
>>>>    optionally including all subclasses of the specified class (-s)
>>>>    for each class, also list all of its interfaces (-i)
>>>> 
>>>> The hex value in the output is the address of the ClassLoaderData for the ClassLoader of the class. I did not include the address of the Klass, but could if you think it would be useful. Changing the format of what comes after the classname is easy. Just let me know what you think is best.
>>>> 
>>>> I have not updated any other dcmds to be consistent with how classes are uniquely identified. A separate bug should be filed for that. Actually I thought one was, but I looked through this thread's history and could not find mention of it. I also have not implemented the reverse hierarchy dcmd. JDK-8068830 has already been filed for that, but there are no plans to work on it in the near term.
>>>> 
>>>> thanks,
>>>> 
>>>> Chris
>> 
> 



More information about the hotspot-runtime-dev mailing list