Mercurial > hg > truffle
annotate src/share/vm/services/classLoadingService.cpp @ 1145:e018e6884bd8
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
author | ysr |
---|---|
date | Wed, 23 Dec 2009 09:23:54 -0800 |
parents | a61af66fc99e |
children | 75bd253e25dd |
rev | line source |
---|---|
0 | 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 */ | |
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; | |
1145
e018e6884bd8
6631166: CMS: better heuristics when combatting fragmentation
ysr
parents:
0
diff
changeset
|
131 gclog_or_tty->print_cr("[Unloading class %s]", k->external_name()); |
0 | 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 } |