src/share/vm/classfile/classLoaderStats.cpp

Sat, 24 Oct 2020 16:43:47 +0800

author
aoqi
date
Sat, 24 Oct 2020 16:43:47 +0800
changeset 10015
eb7ce841ccec
parent 9063
777ace6655eb
permissions
-rw-r--r--

Merge

     1 /*
     2  * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.
     8  *
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    12  * version 2 for more details (a copy is included in the LICENSE file that
    13  * accompanied this code).
    14  *
    15  * You should have received a copy of the GNU General Public License version
    16  * 2 along with this work; if not, write to the Free Software Foundation,
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    18  *
    19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    20  * or visit www.oracle.com if you need additional information or have any
    21  * questions.
    22  *
    23  */
    25 #include "precompiled.hpp"
    26 #include "classfile/classLoaderStats.hpp"
    27 #include "utilities/globalDefinitions.hpp"
    30 class ClassStatsClosure : public KlassClosure {
    31 public:
    32   int _num_classes;
    34   ClassStatsClosure() :
    35     _num_classes(0) {
    36   }
    38   virtual void do_klass(Klass* k) {
    39     _num_classes++;
    40   }
    41 };
    44 void ClassLoaderStatsClosure::do_cld(ClassLoaderData* cld) {
    45   oop cl = cld->class_loader();
    46   ClassLoaderStats* cls;
    48   // The hashtable key is the ClassLoader oop since we want to account
    49   // for "real" classes and anonymous classes together
    50   ClassLoaderStats** cls_ptr = _stats->get(cl);
    51   if (cls_ptr == NULL) {
    52     cls = new ClassLoaderStats();
    53     _stats->put(cl, cls);
    54     _total_loaders++;
    55   } else {
    56     cls = *cls_ptr;
    57   }
    59   if (!cld->is_anonymous()) {
    60     cls->_cld = cld;
    61   }
    63   cls->_class_loader = cl;
    64   if (cl != NULL) {
    65     cls->_parent = java_lang_ClassLoader::parent(cl);
    66     addEmptyParents(cls->_parent);
    67   }
    69   ClassStatsClosure csc;
    70   cld->classes_do(&csc);
    71   if(cld->is_anonymous()) {
    72     cls->_anon_classes_count += csc._num_classes;
    73   } else {
    74     cls->_classes_count = csc._num_classes;
    75   }
    76   _total_classes += csc._num_classes;
    78   Metaspace* ms = cld->metaspace_or_null();
    79   if (ms != NULL) {
    80     if(cld->is_anonymous()) {
    81       cls->_anon_chunk_sz += ms->allocated_chunks_bytes();
    82       cls->_anon_block_sz += ms->allocated_blocks_bytes();
    83     } else {
    84       cls->_chunk_sz = ms->allocated_chunks_bytes();
    85       cls->_block_sz = ms->allocated_blocks_bytes();
    86     }
    87     _total_chunk_sz += ms->allocated_chunks_bytes();
    88     _total_block_sz += ms->allocated_blocks_bytes();
    89   }
    90 }
    93 // Handles the difference in pointer width on 32 and 64 bit platforms
    94 #ifdef _LP64
    95   #define SPACE "%8s"
    96 #else
    97   #define SPACE "%s"
    98 #endif
   101 bool ClassLoaderStatsClosure::do_entry(oop const& key, ClassLoaderStats* const& cls) {
   102   Klass* class_loader_klass = (cls->_class_loader == NULL ? NULL : cls->_class_loader->klass());
   103   Klass* parent_klass = (cls->_parent == NULL ? NULL : cls->_parent->klass());
   105   _out->print(INTPTR_FORMAT "  " INTPTR_FORMAT "  " INTPTR_FORMAT "  " UINTX_FORMAT_W(6) "  " SIZE_FORMAT_W(8) "  " SIZE_FORMAT_W(8) "  ",
   106       p2i(class_loader_klass), p2i(parent_klass), p2i(cls->_cld),
   107       cls->_classes_count,
   108       cls->_chunk_sz, cls->_block_sz);
   109   if (class_loader_klass != NULL) {
   110     _out->print("%s", class_loader_klass->external_name());
   111   } else {
   112     _out->print("<boot class loader>");
   113   }
   114   _out->cr();
   115   if (cls->_anon_classes_count > 0) {
   116     _out->print_cr(SPACE SPACE SPACE "                                    " UINTX_FORMAT_W(6) "  " SIZE_FORMAT_W(8) "  " SIZE_FORMAT_W(8) "   + unsafe anonymous classes",
   117         "", "", "",
   118         cls->_anon_classes_count,
   119         cls->_anon_chunk_sz, cls->_anon_block_sz);
   120   }
   121   return true;
   122 }
   125 void ClassLoaderStatsClosure::print() {
   126   _out->print_cr("ClassLoader" SPACE " Parent" SPACE "      CLD*" SPACE "       Classes   ChunkSz   BlockSz  Type", "", "", "");
   127   _stats->iterate(this);
   128   _out->print("Total = " UINTX_FORMAT_W(-6), _total_loaders);
   129   _out->print(SPACE SPACE SPACE "                      ", "", "", "");
   130   _out->print_cr(UINTX_FORMAT_W(6) "  " SIZE_FORMAT_W(8) "  " SIZE_FORMAT_W(8) "  ",
   131       _total_classes,
   132       _total_chunk_sz,
   133       _total_block_sz);
   134   _out->print_cr("ChunkSz: Total size of all allocated metaspace chunks");
   135   _out->print_cr("BlockSz: Total size of all allocated metaspace blocks (each chunk has several blocks)");
   136 }
   139 void ClassLoaderStatsClosure::addEmptyParents(oop cl) {
   140   while (cl != NULL && java_lang_ClassLoader::loader_data(cl) == NULL) {
   141     // This classloader has not loaded any classes
   142     ClassLoaderStats** cls_ptr = _stats->get(cl);
   143     if (cls_ptr == NULL) {
   144       // It does not exist in our table - add it
   145       ClassLoaderStats* cls = new ClassLoaderStats();
   146       cls->_class_loader = cl;
   147       cls->_parent = java_lang_ClassLoader::parent(cl);
   148       _stats->put(cl, cls);
   149       _total_loaders++;
   150     }
   152     cl = java_lang_ClassLoader::parent(cl);
   153   }
   154 }
   157 void ClassLoaderStatsVMOperation::doit() {
   158   ClassLoaderStatsClosure clsc (_out);
   159   ClassLoaderDataGraph::cld_do(&clsc);
   160   clsc.print();
   161 }
   164 void ClassLoaderStatsDCmd::execute(DCmdSource source, TRAPS) {
   165   ClassLoaderStatsVMOperation op(output());
   166   VMThread::execute(&op);
   167 }

mercurial