Wed, 23 Dec 2009 09:23:54 -0800
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
1 /*
2 * Copyright 2003-2005 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
20 * CA 95054 USA or visit www.sun.com if you need additional information or
21 * have any questions.
22 *
23 */
25 # include "incls/_precompiled.incl"
26 # include "incls/_classLoadingService.cpp.incl"
28 #ifdef DTRACE_ENABLED
30 // Only bother with this argument setup if dtrace is available
32 HS_DTRACE_PROBE_DECL4(hotspot, class__loaded, char*, int, oop, bool);
33 HS_DTRACE_PROBE_DECL4(hotspot, class__unloaded, char*, int, oop, bool);
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 }
48 #else // ndef DTRACE_ENABLED
50 #define DTRACE_CLASSLOAD_PROBE(type, clss, shared)
52 #endif
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;
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;
67 void ClassLoadingService::init() {
68 EXCEPTION_MARK;
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);
77 _classes_unloaded_count =
78 PerfDataManager::create_counter(JAVA_CLS, "unloadedClasses",
79 PerfData::U_Events, CHECK);
81 _shared_classes_loaded_count =
82 PerfDataManager::create_counter(JAVA_CLS, "sharedLoadedClasses",
83 PerfData::U_Events, CHECK);
85 _shared_classes_unloaded_count =
86 PerfDataManager::create_counter(JAVA_CLS, "sharedUnloadedClasses",
87 PerfData::U_Events, CHECK);
89 if (UsePerfData) {
90 _classbytes_loaded =
91 PerfDataManager::create_counter(SUN_CLS, "loadedBytes",
92 PerfData::U_Bytes, CHECK);
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);
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 }
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();
115 if (UsePerfData) {
116 // add the class size
117 size_t size = compute_class_size(k);
118 _classbytes_unloaded->inc(size);
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 }
129 if (TraceClassUnloading) {
130 ResourceMark rm;
131 gclog_or_tty->print_cr("[Unloading class %s]", k->external_name());
132 }
133 }
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();
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 }
151 size_t ClassLoadingService::compute_class_size(instanceKlass* k) {
152 // lifted from ClassStatistics.do_class(klassOop k)
154 size_t class_size = 0;
156 class_size += k->as_klassOop()->size();
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 }
170 bool ClassLoadingService::set_verbose(bool verbose) {
171 MutexLocker m(Management_lock);
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();
178 return verbose;
179 }
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 }
189 GrowableArray<KlassHandle>* LoadedClassesEnumerator::_loaded_classes = NULL;
190 Thread* LoadedClassesEnumerator::_current_thread = NULL;
192 LoadedClassesEnumerator::LoadedClassesEnumerator(Thread* cur_thread) {
193 assert(cur_thread == Thread::current(), "Check current thread");
195 int init_size = ClassLoadingService::loaded_class_count();
196 _klass_handle_array = new GrowableArray<KlassHandle>(init_size);
198 // For consistency of the loaded classes, grab the SystemDictionary lock
199 MutexLocker sd_mutex(SystemDictionary_lock);
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;
208 SystemDictionary::classes_do(&add_loaded_class);
210 // FIXME: Exclude array klasses for now
211 // Universe::basic_type_classes_do(&add_loaded_class);
212 }