1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/vm/classfile/classLoaderStats.cpp Mon Dec 25 00:08:23 2017 -0500 1.3 @@ -0,0 +1,167 @@ 1.4 +/* 1.5 + * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. 1.11 + * 1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.15 + * version 2 for more details (a copy is included in the LICENSE file that 1.16 + * accompanied this code). 1.17 + * 1.18 + * You should have received a copy of the GNU General Public License version 1.19 + * 2 along with this work; if not, write to the Free Software Foundation, 1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.21 + * 1.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1.23 + * or visit www.oracle.com if you need additional information or have any 1.24 + * questions. 1.25 + * 1.26 + */ 1.27 + 1.28 +#include "precompiled.hpp" 1.29 +#include "classfile/classLoaderStats.hpp" 1.30 +#include "utilities/globalDefinitions.hpp" 1.31 + 1.32 + 1.33 +class ClassStatsClosure : public KlassClosure { 1.34 +public: 1.35 + int _num_classes; 1.36 + 1.37 + ClassStatsClosure() : 1.38 + _num_classes(0) { 1.39 + } 1.40 + 1.41 + virtual void do_klass(Klass* k) { 1.42 + _num_classes++; 1.43 + } 1.44 +}; 1.45 + 1.46 + 1.47 +void ClassLoaderStatsClosure::do_cld(ClassLoaderData* cld) { 1.48 + oop cl = cld->class_loader(); 1.49 + ClassLoaderStats* cls; 1.50 + 1.51 + // The hashtable key is the ClassLoader oop since we want to account 1.52 + // for "real" classes and anonymous classes together 1.53 + ClassLoaderStats** cls_ptr = _stats->get(cl); 1.54 + if (cls_ptr == NULL) { 1.55 + cls = new ClassLoaderStats(); 1.56 + _stats->put(cl, cls); 1.57 + _total_loaders++; 1.58 + } else { 1.59 + cls = *cls_ptr; 1.60 + } 1.61 + 1.62 + if (!cld->is_anonymous()) { 1.63 + cls->_cld = cld; 1.64 + } 1.65 + 1.66 + cls->_class_loader = cl; 1.67 + if (cl != NULL) { 1.68 + cls->_parent = java_lang_ClassLoader::parent(cl); 1.69 + addEmptyParents(cls->_parent); 1.70 + } 1.71 + 1.72 + ClassStatsClosure csc; 1.73 + cld->classes_do(&csc); 1.74 + if(cld->is_anonymous()) { 1.75 + cls->_anon_classes_count += csc._num_classes; 1.76 + } else { 1.77 + cls->_classes_count = csc._num_classes; 1.78 + } 1.79 + _total_classes += csc._num_classes; 1.80 + 1.81 + Metaspace* ms = cld->metaspace_or_null(); 1.82 + if (ms != NULL) { 1.83 + if(cld->is_anonymous()) { 1.84 + cls->_anon_chunk_sz += ms->allocated_chunks_bytes(); 1.85 + cls->_anon_block_sz += ms->allocated_blocks_bytes(); 1.86 + } else { 1.87 + cls->_chunk_sz = ms->allocated_chunks_bytes(); 1.88 + cls->_block_sz = ms->allocated_blocks_bytes(); 1.89 + } 1.90 + _total_chunk_sz += ms->allocated_chunks_bytes(); 1.91 + _total_block_sz += ms->allocated_blocks_bytes(); 1.92 + } 1.93 +} 1.94 + 1.95 + 1.96 +// Handles the difference in pointer width on 32 and 64 bit platforms 1.97 +#ifdef _LP64 1.98 + #define SPACE "%8s" 1.99 +#else 1.100 + #define SPACE "%s" 1.101 +#endif 1.102 + 1.103 + 1.104 +bool ClassLoaderStatsClosure::do_entry(oop const& key, ClassLoaderStats* const& cls) { 1.105 + Klass* class_loader_klass = (cls->_class_loader == NULL ? NULL : cls->_class_loader->klass()); 1.106 + Klass* parent_klass = (cls->_parent == NULL ? NULL : cls->_parent->klass()); 1.107 + 1.108 + _out->print(INTPTR_FORMAT " " INTPTR_FORMAT " " INTPTR_FORMAT " " UINTX_FORMAT_W(6) " " SIZE_FORMAT_W(8) " " SIZE_FORMAT_W(8) " ", 1.109 + p2i(class_loader_klass), p2i(parent_klass), p2i(cls->_cld), 1.110 + cls->_classes_count, 1.111 + cls->_chunk_sz, cls->_block_sz); 1.112 + if (class_loader_klass != NULL) { 1.113 + _out->print("%s", class_loader_klass->external_name()); 1.114 + } else { 1.115 + _out->print("<boot class loader>"); 1.116 + } 1.117 + _out->cr(); 1.118 + if (cls->_anon_classes_count > 0) { 1.119 + _out->print_cr(SPACE SPACE SPACE " " UINTX_FORMAT_W(6) " " SIZE_FORMAT_W(8) " " SIZE_FORMAT_W(8) " + unsafe anonymous classes", 1.120 + "", "", "", 1.121 + cls->_anon_classes_count, 1.122 + cls->_anon_chunk_sz, cls->_anon_block_sz); 1.123 + } 1.124 + return true; 1.125 +} 1.126 + 1.127 + 1.128 +void ClassLoaderStatsClosure::print() { 1.129 + _out->print_cr("ClassLoader" SPACE " Parent" SPACE " CLD*" SPACE " Classes ChunkSz BlockSz Type", "", "", ""); 1.130 + _stats->iterate(this); 1.131 + _out->print("Total = " UINTX_FORMAT_W(-6), _total_loaders); 1.132 + _out->print(SPACE SPACE SPACE " ", "", "", ""); 1.133 + _out->print_cr(UINTX_FORMAT_W(6) " " SIZE_FORMAT_W(8) " " SIZE_FORMAT_W(8) " ", 1.134 + _total_classes, 1.135 + _total_chunk_sz, 1.136 + _total_block_sz); 1.137 + _out->print_cr("ChunkSz: Total size of all allocated metaspace chunks"); 1.138 + _out->print_cr("BlockSz: Total size of all allocated metaspace blocks (each chunk has several blocks)"); 1.139 +} 1.140 + 1.141 + 1.142 +void ClassLoaderStatsClosure::addEmptyParents(oop cl) { 1.143 + while (cl != NULL && java_lang_ClassLoader::loader_data(cl) == NULL) { 1.144 + // This classloader has not loaded any classes 1.145 + ClassLoaderStats** cls_ptr = _stats->get(cl); 1.146 + if (cls_ptr == NULL) { 1.147 + // It does not exist in our table - add it 1.148 + ClassLoaderStats* cls = new ClassLoaderStats(); 1.149 + cls->_class_loader = cl; 1.150 + cls->_parent = java_lang_ClassLoader::parent(cl); 1.151 + _stats->put(cl, cls); 1.152 + _total_loaders++; 1.153 + } 1.154 + 1.155 + cl = java_lang_ClassLoader::parent(cl); 1.156 + } 1.157 +} 1.158 + 1.159 + 1.160 +void ClassLoaderStatsVMOperation::doit() { 1.161 + ClassLoaderStatsClosure clsc (_out); 1.162 + ClassLoaderDataGraph::cld_do(&clsc); 1.163 + clsc.print(); 1.164 +} 1.165 + 1.166 + 1.167 +void ClassLoaderStatsDCmd::execute(DCmdSource source, TRAPS) { 1.168 + ClassLoaderStatsVMOperation op(output()); 1.169 + VMThread::execute(&op); 1.170 +}