1 /* 2 * Copyright (c) 2003, 2005, 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 */ 24 25 # include "incls/_precompiled.incl" 26 # include "incls/_classLoadingService.cpp.incl" 27 28 #ifdef DTRACE_ENABLED 29 30 // Only bother with this argument setup if dtrace is available 31 32 HS_DTRACE_PROBE_DECL4(hotspot, class__loaded, char*, int, oop, bool); 33 HS_DTRACE_PROBE_DECL4(hotspot, class__unloaded, char*, int, oop, bool); 34 35 #define DTRACE_CLASSLOAD_PROBE(type, clss, shared) \ 36 { \ 37 char* data = NULL; \ 38 int len = 0; \ 39 symbolOop name = (clss)->name(); \ 40 if (name != NULL) { \ 41 data = (char*)name->bytes(); \ 42 len = name->utf8_length(); \ 43 } \ 44 HS_DTRACE_PROBE4(hotspot, class__##type, \ 45 data, len, (clss)->class_loader(), (shared)); \ 46 } 47 48 #else // ndef DTRACE_ENABLED 49 50 #define DTRACE_CLASSLOAD_PROBE(type, clss, shared) 51 52 #endif 53 54 // counters for classes loaded from class files 55 PerfCounter* ClassLoadingService::_classes_loaded_count = NULL; 56 PerfCounter* ClassLoadingService::_classes_unloaded_count = NULL; 57 PerfCounter* ClassLoadingService::_classbytes_loaded = NULL; 58 PerfCounter* ClassLoadingService::_classbytes_unloaded = NULL; 59 60 // counters for classes loaded from shared archive 61 PerfCounter* ClassLoadingService::_shared_classes_loaded_count = NULL; 62 PerfCounter* ClassLoadingService::_shared_classes_unloaded_count = NULL; 63 PerfCounter* ClassLoadingService::_shared_classbytes_loaded = NULL; 64 PerfCounter* ClassLoadingService::_shared_classbytes_unloaded = NULL; 65 PerfVariable* ClassLoadingService::_class_methods_size = NULL; 66 67 void ClassLoadingService::init() { 68 EXCEPTION_MARK; 69 70 // These counters are for java.lang.management API support. 71 // They are created even if -XX:-UsePerfData is set and in 72 // that case, they will be allocated on C heap. 73 _classes_loaded_count = 74 PerfDataManager::create_counter(JAVA_CLS, "loadedClasses", 75 PerfData::U_Events, CHECK); 76 77 _classes_unloaded_count = 78 PerfDataManager::create_counter(JAVA_CLS, "unloadedClasses", 79 PerfData::U_Events, CHECK); 80 81 _shared_classes_loaded_count = 82 PerfDataManager::create_counter(JAVA_CLS, "sharedLoadedClasses", 83 PerfData::U_Events, CHECK); 84 85 _shared_classes_unloaded_count = 86 PerfDataManager::create_counter(JAVA_CLS, "sharedUnloadedClasses", 87 PerfData::U_Events, CHECK); 88 89 if (UsePerfData) { 90 _classbytes_loaded = 91 PerfDataManager::create_counter(SUN_CLS, "loadedBytes", 92 PerfData::U_Bytes, CHECK); 93 94 _classbytes_unloaded = 95 PerfDataManager::create_counter(SUN_CLS, "unloadedBytes", 96 PerfData::U_Bytes, CHECK); 97 _shared_classbytes_loaded = 98 PerfDataManager::create_counter(SUN_CLS, "sharedLoadedBytes", 99 PerfData::U_Bytes, CHECK); 100 101 _shared_classbytes_unloaded = 102 PerfDataManager::create_counter(SUN_CLS, "sharedUnloadedBytes", 103 PerfData::U_Bytes, CHECK); 104 _class_methods_size = 105 PerfDataManager::create_variable(SUN_CLS, "methodBytes", 106 PerfData::U_Bytes, CHECK); 107 } 108 } 109 110 void ClassLoadingService::notify_class_unloaded(instanceKlass* k) { 111 DTRACE_CLASSLOAD_PROBE(unloaded, k, false); 112 // Classes that can be unloaded must be non-shared 113 _classes_unloaded_count->inc(); 114 115 if (UsePerfData) { 116 // add the class size 117 size_t size = compute_class_size(k); 118 _classbytes_unloaded->inc(size); 119 120 // Compute method size & subtract from running total. 121 // We are called during phase 1 of mark sweep, so it's 122 // still ok to iterate through methodOops here. 123 objArrayOop methods = k->methods(); 124 for (int i = 0; i < methods->length(); i++) { 125 _class_methods_size->inc(-methods->obj_at(i)->size()); 126 } 127 } 128 129 if (TraceClassUnloading) { 130 ResourceMark rm; 131 tty->print_cr("[Unloading class %s]", k->external_name()); 132 } 133 } 134 135 void ClassLoadingService::notify_class_loaded(instanceKlass* k, bool shared_class) { 136 DTRACE_CLASSLOAD_PROBE(loaded, k, shared_class); 137 PerfCounter* classes_counter = (shared_class ? _shared_classes_loaded_count 138 : _classes_loaded_count); 139 // increment the count 140 classes_counter->inc(); 141 142 if (UsePerfData) { 143 PerfCounter* classbytes_counter = (shared_class ? _shared_classbytes_loaded 144 : _classbytes_loaded); 145 // add the class size 146 size_t size = compute_class_size(k); 147 classbytes_counter->inc(size); 148 } 149 } 150 151 size_t ClassLoadingService::compute_class_size(instanceKlass* k) { 152 // lifted from ClassStatistics.do_class(klassOop k) 153 154 size_t class_size = 0; 155 156 class_size += k->as_klassOop()->size(); 157 158 if (k->oop_is_instance()) { 159 class_size += k->methods()->size(); 160 class_size += k->constants()->size(); 161 class_size += k->local_interfaces()->size(); 162 class_size += k->transitive_interfaces()->size(); 163 // We do not have to count implementors, since we only store one! 164 class_size += k->fields()->size(); 165 } 166 return class_size * oopSize; 167 } 168 169 170 bool ClassLoadingService::set_verbose(bool verbose) { 171 MutexLocker m(Management_lock); 172 173 // verbose will be set to the previous value 174 bool succeed = CommandLineFlags::boolAtPut((char*)"TraceClassLoading", &verbose, MANAGEMENT); 175 assert(succeed, "Setting TraceClassLoading flag fails"); 176 reset_trace_class_unloading(); 177 178 return verbose; 179 } 180 181 // Caller to this function must own Management_lock 182 void ClassLoadingService::reset_trace_class_unloading() { 183 assert(Management_lock->owned_by_self(), "Must own the Management_lock"); 184 bool value = MemoryService::get_verbose() || ClassLoadingService::get_verbose(); 185 bool succeed = CommandLineFlags::boolAtPut((char*)"TraceClassUnloading", &value, MANAGEMENT); 186 assert(succeed, "Setting TraceClassUnLoading flag fails"); 187 } 188 189 GrowableArray<KlassHandle>* LoadedClassesEnumerator::_loaded_classes = NULL; 190 Thread* LoadedClassesEnumerator::_current_thread = NULL; 191 192 LoadedClassesEnumerator::LoadedClassesEnumerator(Thread* cur_thread) { 193 assert(cur_thread == Thread::current(), "Check current thread"); 194 195 int init_size = ClassLoadingService::loaded_class_count(); 196 _klass_handle_array = new GrowableArray<KlassHandle>(init_size); 197 198 // For consistency of the loaded classes, grab the SystemDictionary lock 199 MutexLocker sd_mutex(SystemDictionary_lock); 200 201 // Set _loaded_classes and _current_thread and begin enumerating all classes. 202 // Only one thread will do the enumeration at a time. 203 // These static variables are needed and they are used by the static method 204 // add_loaded_class called from classes_do(). 205 _loaded_classes = _klass_handle_array; 206 _current_thread = cur_thread; 207 208 SystemDictionary::classes_do(&add_loaded_class); 209 210 // FIXME: Exclude array klasses for now 211 // Universe::basic_type_classes_do(&add_loaded_class); 212 }