src/share/vm/services/classLoadingService.cpp

Wed, 23 Dec 2009 09:23:54 -0800

author
ysr
date
Wed, 23 Dec 2009 09:23:54 -0800
changeset 1580
e018e6884bd8
parent 435
a61af66fc99e
child 1582
75bd253e25dd
permissions
-rw-r--r--

6631166: CMS: better heuristics when combatting fragmentation
Summary: Autonomic per-worker free block cache sizing, tunable coalition policies, fixes to per-size block statistics, retuned gain and bandwidth of some feedback loop filters to allow quicker reactivity to abrupt changes in ambient demand, and other heuristics to reduce fragmentation of the CMS old gen. Also tightened some assertions, including those related to locking.
Reviewed-by: jmasa

duke@435 1 /*
duke@435 2 * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved.
duke@435 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
duke@435 4 *
duke@435 5 * This code is free software; you can redistribute it and/or modify it
duke@435 6 * under the terms of the GNU General Public License version 2 only, as
duke@435 7 * published by the Free Software Foundation.
duke@435 8 *
duke@435 9 * This code is distributed in the hope that it will be useful, but WITHOUT
duke@435 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
duke@435 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
duke@435 12 * version 2 for more details (a copy is included in the LICENSE file that
duke@435 13 * accompanied this code).
duke@435 14 *
duke@435 15 * You should have received a copy of the GNU General Public License version
duke@435 16 * 2 along with this work; if not, write to the Free Software Foundation,
duke@435 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
duke@435 18 *
duke@435 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
duke@435 20 * CA 95054 USA or visit www.sun.com if you need additional information or
duke@435 21 * have any questions.
duke@435 22 *
duke@435 23 */
duke@435 24
duke@435 25 # include "incls/_precompiled.incl"
duke@435 26 # include "incls/_classLoadingService.cpp.incl"
duke@435 27
duke@435 28 #ifdef DTRACE_ENABLED
duke@435 29
duke@435 30 // Only bother with this argument setup if dtrace is available
duke@435 31
duke@435 32 HS_DTRACE_PROBE_DECL4(hotspot, class__loaded, char*, int, oop, bool);
duke@435 33 HS_DTRACE_PROBE_DECL4(hotspot, class__unloaded, char*, int, oop, bool);
duke@435 34
duke@435 35 #define DTRACE_CLASSLOAD_PROBE(type, clss, shared) \
duke@435 36 { \
duke@435 37 char* data = NULL; \
duke@435 38 int len = 0; \
duke@435 39 symbolOop name = (clss)->name(); \
duke@435 40 if (name != NULL) { \
duke@435 41 data = (char*)name->bytes(); \
duke@435 42 len = name->utf8_length(); \
duke@435 43 } \
duke@435 44 HS_DTRACE_PROBE4(hotspot, class__##type, \
duke@435 45 data, len, (clss)->class_loader(), (shared)); \
duke@435 46 }
duke@435 47
duke@435 48 #else // ndef DTRACE_ENABLED
duke@435 49
duke@435 50 #define DTRACE_CLASSLOAD_PROBE(type, clss, shared)
duke@435 51
duke@435 52 #endif
duke@435 53
duke@435 54 // counters for classes loaded from class files
duke@435 55 PerfCounter* ClassLoadingService::_classes_loaded_count = NULL;
duke@435 56 PerfCounter* ClassLoadingService::_classes_unloaded_count = NULL;
duke@435 57 PerfCounter* ClassLoadingService::_classbytes_loaded = NULL;
duke@435 58 PerfCounter* ClassLoadingService::_classbytes_unloaded = NULL;
duke@435 59
duke@435 60 // counters for classes loaded from shared archive
duke@435 61 PerfCounter* ClassLoadingService::_shared_classes_loaded_count = NULL;
duke@435 62 PerfCounter* ClassLoadingService::_shared_classes_unloaded_count = NULL;
duke@435 63 PerfCounter* ClassLoadingService::_shared_classbytes_loaded = NULL;
duke@435 64 PerfCounter* ClassLoadingService::_shared_classbytes_unloaded = NULL;
duke@435 65 PerfVariable* ClassLoadingService::_class_methods_size = NULL;
duke@435 66
duke@435 67 void ClassLoadingService::init() {
duke@435 68 EXCEPTION_MARK;
duke@435 69
duke@435 70 // These counters are for java.lang.management API support.
duke@435 71 // They are created even if -XX:-UsePerfData is set and in
duke@435 72 // that case, they will be allocated on C heap.
duke@435 73 _classes_loaded_count =
duke@435 74 PerfDataManager::create_counter(JAVA_CLS, "loadedClasses",
duke@435 75 PerfData::U_Events, CHECK);
duke@435 76
duke@435 77 _classes_unloaded_count =
duke@435 78 PerfDataManager::create_counter(JAVA_CLS, "unloadedClasses",
duke@435 79 PerfData::U_Events, CHECK);
duke@435 80
duke@435 81 _shared_classes_loaded_count =
duke@435 82 PerfDataManager::create_counter(JAVA_CLS, "sharedLoadedClasses",
duke@435 83 PerfData::U_Events, CHECK);
duke@435 84
duke@435 85 _shared_classes_unloaded_count =
duke@435 86 PerfDataManager::create_counter(JAVA_CLS, "sharedUnloadedClasses",
duke@435 87 PerfData::U_Events, CHECK);
duke@435 88
duke@435 89 if (UsePerfData) {
duke@435 90 _classbytes_loaded =
duke@435 91 PerfDataManager::create_counter(SUN_CLS, "loadedBytes",
duke@435 92 PerfData::U_Bytes, CHECK);
duke@435 93
duke@435 94 _classbytes_unloaded =
duke@435 95 PerfDataManager::create_counter(SUN_CLS, "unloadedBytes",
duke@435 96 PerfData::U_Bytes, CHECK);
duke@435 97 _shared_classbytes_loaded =
duke@435 98 PerfDataManager::create_counter(SUN_CLS, "sharedLoadedBytes",
duke@435 99 PerfData::U_Bytes, CHECK);
duke@435 100
duke@435 101 _shared_classbytes_unloaded =
duke@435 102 PerfDataManager::create_counter(SUN_CLS, "sharedUnloadedBytes",
duke@435 103 PerfData::U_Bytes, CHECK);
duke@435 104 _class_methods_size =
duke@435 105 PerfDataManager::create_variable(SUN_CLS, "methodBytes",
duke@435 106 PerfData::U_Bytes, CHECK);
duke@435 107 }
duke@435 108 }
duke@435 109
duke@435 110 void ClassLoadingService::notify_class_unloaded(instanceKlass* k) {
duke@435 111 DTRACE_CLASSLOAD_PROBE(unloaded, k, false);
duke@435 112 // Classes that can be unloaded must be non-shared
duke@435 113 _classes_unloaded_count->inc();
duke@435 114
duke@435 115 if (UsePerfData) {
duke@435 116 // add the class size
duke@435 117 size_t size = compute_class_size(k);
duke@435 118 _classbytes_unloaded->inc(size);
duke@435 119
duke@435 120 // Compute method size & subtract from running total.
duke@435 121 // We are called during phase 1 of mark sweep, so it's
duke@435 122 // still ok to iterate through methodOops here.
duke@435 123 objArrayOop methods = k->methods();
duke@435 124 for (int i = 0; i < methods->length(); i++) {
duke@435 125 _class_methods_size->inc(-methods->obj_at(i)->size());
duke@435 126 }
duke@435 127 }
duke@435 128
duke@435 129 if (TraceClassUnloading) {
duke@435 130 ResourceMark rm;
ysr@1580 131 gclog_or_tty->print_cr("[Unloading class %s]", k->external_name());
duke@435 132 }
duke@435 133 }
duke@435 134
duke@435 135 void ClassLoadingService::notify_class_loaded(instanceKlass* k, bool shared_class) {
duke@435 136 DTRACE_CLASSLOAD_PROBE(loaded, k, shared_class);
duke@435 137 PerfCounter* classes_counter = (shared_class ? _shared_classes_loaded_count
duke@435 138 : _classes_loaded_count);
duke@435 139 // increment the count
duke@435 140 classes_counter->inc();
duke@435 141
duke@435 142 if (UsePerfData) {
duke@435 143 PerfCounter* classbytes_counter = (shared_class ? _shared_classbytes_loaded
duke@435 144 : _classbytes_loaded);
duke@435 145 // add the class size
duke@435 146 size_t size = compute_class_size(k);
duke@435 147 classbytes_counter->inc(size);
duke@435 148 }
duke@435 149 }
duke@435 150
duke@435 151 size_t ClassLoadingService::compute_class_size(instanceKlass* k) {
duke@435 152 // lifted from ClassStatistics.do_class(klassOop k)
duke@435 153
duke@435 154 size_t class_size = 0;
duke@435 155
duke@435 156 class_size += k->as_klassOop()->size();
duke@435 157
duke@435 158 if (k->oop_is_instance()) {
duke@435 159 class_size += k->methods()->size();
duke@435 160 class_size += k->constants()->size();
duke@435 161 class_size += k->local_interfaces()->size();
duke@435 162 class_size += k->transitive_interfaces()->size();
duke@435 163 // We do not have to count implementors, since we only store one!
duke@435 164 class_size += k->fields()->size();
duke@435 165 }
duke@435 166 return class_size * oopSize;
duke@435 167 }
duke@435 168
duke@435 169
duke@435 170 bool ClassLoadingService::set_verbose(bool verbose) {
duke@435 171 MutexLocker m(Management_lock);
duke@435 172
duke@435 173 // verbose will be set to the previous value
duke@435 174 bool succeed = CommandLineFlags::boolAtPut((char*)"TraceClassLoading", &verbose, MANAGEMENT);
duke@435 175 assert(succeed, "Setting TraceClassLoading flag fails");
duke@435 176 reset_trace_class_unloading();
duke@435 177
duke@435 178 return verbose;
duke@435 179 }
duke@435 180
duke@435 181 // Caller to this function must own Management_lock
duke@435 182 void ClassLoadingService::reset_trace_class_unloading() {
duke@435 183 assert(Management_lock->owned_by_self(), "Must own the Management_lock");
duke@435 184 bool value = MemoryService::get_verbose() || ClassLoadingService::get_verbose();
duke@435 185 bool succeed = CommandLineFlags::boolAtPut((char*)"TraceClassUnloading", &value, MANAGEMENT);
duke@435 186 assert(succeed, "Setting TraceClassUnLoading flag fails");
duke@435 187 }
duke@435 188
duke@435 189 GrowableArray<KlassHandle>* LoadedClassesEnumerator::_loaded_classes = NULL;
duke@435 190 Thread* LoadedClassesEnumerator::_current_thread = NULL;
duke@435 191
duke@435 192 LoadedClassesEnumerator::LoadedClassesEnumerator(Thread* cur_thread) {
duke@435 193 assert(cur_thread == Thread::current(), "Check current thread");
duke@435 194
duke@435 195 int init_size = ClassLoadingService::loaded_class_count();
duke@435 196 _klass_handle_array = new GrowableArray<KlassHandle>(init_size);
duke@435 197
duke@435 198 // For consistency of the loaded classes, grab the SystemDictionary lock
duke@435 199 MutexLocker sd_mutex(SystemDictionary_lock);
duke@435 200
duke@435 201 // Set _loaded_classes and _current_thread and begin enumerating all classes.
duke@435 202 // Only one thread will do the enumeration at a time.
duke@435 203 // These static variables are needed and they are used by the static method
duke@435 204 // add_loaded_class called from classes_do().
duke@435 205 _loaded_classes = _klass_handle_array;
duke@435 206 _current_thread = cur_thread;
duke@435 207
duke@435 208 SystemDictionary::classes_do(&add_loaded_class);
duke@435 209
duke@435 210 // FIXME: Exclude array klasses for now
duke@435 211 // Universe::basic_type_classes_do(&add_loaded_class);
duke@435 212 }

mercurial