RFR(s): 8203682: Add jcmd "VM.classloaders" command to print out class loader hierarchy, details

Kirk Pepperdine kirk.pepperdine at gmail.com
Mon Jun 4 18:56:35 UTC 2018


> 
>> I don't like the use of mtInternal, but there doesn't seem to be a better
>> category (or one to add).
> 
> The point is moot now since I followed your suggestion below, using
> resource area instead.
> 
>> 
>> 152     if (_loader_oop != NULL) {
>> 153       loader_klass = _loader_oop->klass();
>> 154       if (loader_klass != NULL) {
>> 155         loader_class_name = loader_klass->external_name();
>> 156       }
>> 157       oop nameOop = java_lang_ClassLoader::name(_loader_oop);
>> 158       if (nameOop != NULL) {
>> 159         const char* s = java_lang_String::as_utf8_string(nameOop);
>> 160         if (s != NULL) {
>> 161           loader_name = s;
>> 162         }
>> 163       }
>> 
>> These are available to the ClassLoaderData (_cld) as class_loader_name() and
>> class_loader_klass().  I would rather see ClassLoaderData::loader_name()
>> used - once fixed. Also, I don't like <unnamed> in the output.  It seems
>> that most class loaders will be unnamed, so the output will be too noisy
>> with that.  Also, there's an unnamed module so that makes it very confusing.
> 
> Okay to all of that. I changed the coding to use
> class_loader_{klass|name} consistently and only print out loader names
> when set:
> 
> 24942:
> +-- <bootstrap>
>      |
>      +-- "platform", instance of
> jdk.internal.loader.ClassLoaders$PlatformClassLoader
>            |
>            +-- "app", instance of
> jdk.internal.loader.ClassLoaders$AppClassLoader
>                  |
>                  +--
> test3.internals.InMemoryJavaFileManager$InMemoryClassLoader
> 
> 
> See more examples:
> http://cr.openjdk.java.net/~stuefe/webrevs/8203682-jcmd-print-classloader-hierarchy/out2.txt
> http://cr.openjdk.java.net/~stuefe/webrevs/8203682-jcmd-print-classloader-hierarchy/out3.txt
> 
>> 
>> Since this is in a safepoint, maybe you can add a ResourceMark at 472,
>> remove it from 362 and make all classes ResourceObj allocated. Then you can
>> remove the code to delete the types.
>> 
> 
> I originally did not do it since I did not know whether
> ClassLoaderDataGraph::cld_do() would use resource marks. But it does
> not, and you are right, this makes the coding simpler.
> 
>> Can you add assert that you are at a safepoint at the beginning of this, so
>> you don't have to worry about LoaderTreeNode::_loader_oop getting collected.
> 
> Done. (only in full webrev, sorry, I messed up the delta)
> 
>> It seems that by saving _cld in LoaderTreeNode, that you don't need
>> _loader_oop.
> 
> Unfortunately not. To add a node to the tree, I need its parent node.
> At that time I may not yet have encountered the parent loader CLD. So
> I add the parent node, and mark it with the parent loader oop. Later,
> when I encounter the CLD for the parent, I complete the node.
> I added a comment to make that clearer.
> 
>> 
>> This code looks like it's walking the CLDG in order to make a different
>> Class loader graph for printing.  Is it necessary to show the hierarchy
>> information?
>> 
> 
> It proved useful in the classic delegation scenarios.
> 
>> It seems like printing the address is better than <unnamed>, which is what
>> I've looked at with the system dictionary logging.
>> 
> 
> Oh, I do that, when option "verbose" is given:
> 
> +-- <bootstrap>
>      |
>      |               Loader Data: 0x00007fc458239040
>      |              Loader Klass: 0x0000000000000000
>      |                Loader Oop: 0x0000000000000000
>      |
>      +-- "platform", instance of
> jdk.internal.loader.ClassLoaders$PlatformClassLoader
>            |
>            |               Loader Data: 0x00007fc4583f7350
>            |              Loader Klass: 0x00000008000107b0
>            |                Loader Oop: 0x000000060d077b90
>            |
>            +-- "app", instance of
> jdk.internal.loader.ClassLoaders$AppClassLoader
>                  |
>                  |               Loader Data: 0x00007fc4583eb740
>                  |              Loader Klass: 0x0000000800010348
>                  |                Loader Oop: 0x000000060d079b30
>                  |
> 
> I wondered whether I should print the loader oop more prominently, and
> always. Should I? For example:
> 
>      +-- {0x000000060d077b90} "platform", instance of
> jdk.internal.loader.ClassLoaders$PlatformClassLoader
>            |
>            |               Loader Data: 0x00007fc4583f7350
>            |              Loader Klass: 0x00000008000107b0
>            |
>            +-- {0x000000060d079b30} "app", instance of
> jdk.internal.loader.ClassLoaders$AppClassLoader
>                  |
>                  |               Loader Data: 0x00007fc4583eb740
>                  |              Loader Klass: 0x0000000800010348

I can bike shed here… 

“platform”,jdk.internal.loader.ClassLoaders$PlatformClassLoader{0x000000060d077b90}
           |
           |               Loader Data: 0x00007fc4583f7350
           |              Loader Klass: 0x00000008000107b0
           |
           +--  "app",jdk.internal.loader.ClassLoaders$AppClassLoader{0x000000060d079b30}
                 |
                 |               Loader Data: 0x00007fc4583eb740
                 |              Loader Klass: 0x0000000800010348

Kind regards,
Kirk



More information about the hotspot-runtime-dev mailing list