1 /* 2 * Copyright (c) 2003, 2013, 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 "precompiled.hpp" 26 #include "classfile/systemDictionary.hpp" 27 #include "classfile/vmSymbols.hpp" 28 #include "oops/oop.inline.hpp" 29 #include "runtime/handles.inline.hpp" 30 #include "runtime/javaCalls.hpp" 31 #include "runtime/orderAccess.inline.hpp" 32 #include "services/lowMemoryDetector.hpp" 33 #include "services/management.hpp" 34 #include "services/memoryManager.hpp" 35 #include "services/memoryPool.hpp" 36 #include "services/memoryService.hpp" 37 #include "services/gcNotifier.hpp" 38 #include "utilities/dtrace.hpp" 39 40 #ifndef USDT2 41 HS_DTRACE_PROBE_DECL8(hotspot, mem__pool__gc__begin, char*, int, char*, int, 42 size_t, size_t, size_t, size_t); 43 HS_DTRACE_PROBE_DECL8(hotspot, mem__pool__gc__end, char*, int, char*, int, 44 size_t, size_t, size_t, size_t); 45 #endif /* !USDT2 */ 46 47 MemoryManager::MemoryManager() { 48 _num_pools = 0; 49 (void)const_cast<instanceOop&>(_memory_mgr_obj = NULL); 50 } 51 52 void MemoryManager::add_pool(MemoryPool* pool) { 53 assert(_num_pools < MemoryManager::max_num_pools, "_num_pools exceeds the max"); 54 if (_num_pools < MemoryManager::max_num_pools) { 55 _pools[_num_pools] = pool; 56 _num_pools++; 57 } 58 pool->add_manager(this); 59 } 60 61 MemoryManager* MemoryManager::get_code_cache_memory_manager() { 62 return (MemoryManager*) new CodeCacheMemoryManager(); 63 } 64 65 MemoryManager* MemoryManager::get_metaspace_memory_manager() { 66 return (MemoryManager*) new MetaspaceMemoryManager(); 67 } 68 69 GCMemoryManager* MemoryManager::get_copy_memory_manager() { 70 return (GCMemoryManager*) new CopyMemoryManager(); 71 } 72 73 GCMemoryManager* MemoryManager::get_msc_memory_manager() { 74 return (GCMemoryManager*) new MSCMemoryManager(); 75 } 76 77 GCMemoryManager* MemoryManager::get_parnew_memory_manager() { 78 return (GCMemoryManager*) new ParNewMemoryManager(); 79 } 80 81 GCMemoryManager* MemoryManager::get_cms_memory_manager() { 82 return (GCMemoryManager*) new CMSMemoryManager(); 83 } 84 85 GCMemoryManager* MemoryManager::get_psScavenge_memory_manager() { 86 return (GCMemoryManager*) new PSScavengeMemoryManager(); 87 } 88 89 GCMemoryManager* MemoryManager::get_psMarkSweep_memory_manager() { 90 return (GCMemoryManager*) new PSMarkSweepMemoryManager(); 91 } 92 93 GCMemoryManager* MemoryManager::get_g1YoungGen_memory_manager() { 94 return (GCMemoryManager*) new G1YoungGenMemoryManager(); 95 } 96 97 GCMemoryManager* MemoryManager::get_g1OldGen_memory_manager() { 98 return (GCMemoryManager*) new G1OldGenMemoryManager(); 99 } 100 101 GCMemoryManager* MemoryManager::get_epsilon_memory_manager() { 102 return (GCMemoryManager*) new EpsilonMemoryManager(); 103 } 104 105 instanceOop MemoryManager::get_memory_manager_instance(TRAPS) { 106 // Must do an acquire so as to force ordering of subsequent 107 // loads from anything _memory_mgr_obj points to or implies. 108 instanceOop mgr_obj = (instanceOop)OrderAccess::load_ptr_acquire(&_memory_mgr_obj); 109 if (mgr_obj == NULL) { 110 // It's ok for more than one thread to execute the code up to the locked region. 111 // Extra manager instances will just be gc'ed. 112 Klass* k = Management::sun_management_ManagementFactory_klass(CHECK_0); 113 instanceKlassHandle ik(THREAD, k); 114 115 Handle mgr_name = java_lang_String::create_from_str(name(), CHECK_0); 116 117 JavaValue result(T_OBJECT); 118 JavaCallArguments args; 119 args.push_oop(mgr_name); // Argument 1 120 121 Symbol* method_name = NULL; 122 Symbol* signature = NULL; 123 if (is_gc_memory_manager()) { 124 method_name = vmSymbols::createGarbageCollector_name(); 125 signature = vmSymbols::createGarbageCollector_signature(); 126 args.push_oop(Handle()); // Argument 2 (for future extension) 127 } else { 128 method_name = vmSymbols::createMemoryManager_name(); 129 signature = vmSymbols::createMemoryManager_signature(); 130 } 131 132 JavaCalls::call_static(&result, 133 ik, 134 method_name, 135 signature, 136 &args, 137 CHECK_0); 138 139 instanceOop m = (instanceOop) result.get_jobject(); 140 instanceHandle mgr(THREAD, m); 141 142 { 143 // Get lock before setting _memory_mgr_obj 144 // since another thread may have created the instance 145 MutexLocker ml(Management_lock); 146 147 // Check if another thread has created the management object. We reload 148 // _memory_mgr_obj here because some other thread may have initialized 149 // it while we were executing the code before the lock. 150 // 151 // The lock has done an acquire, so the load can't float above it, but 152 // we need to do a load_acquire as above. 153 mgr_obj = (instanceOop)OrderAccess::load_ptr_acquire(&_memory_mgr_obj); 154 if (mgr_obj != NULL) { 155 return mgr_obj; 156 } 157 158 // Get the address of the object we created via call_special. 159 mgr_obj = mgr(); 160 161 // Use store barrier to make sure the memory accesses associated 162 // with creating the management object are visible before publishing 163 // its address. The unlock will publish the store to _memory_mgr_obj 164 // because it does a release first. 165 OrderAccess::release_store_ptr(&_memory_mgr_obj, mgr_obj); 166 } 167 } 168 169 return mgr_obj; 170 } 171 172 void MemoryManager::oops_do(OopClosure* f) { 173 f->do_oop((oop*) &_memory_mgr_obj); 174 } 175 176 GCStatInfo::GCStatInfo(int num_pools) { 177 // initialize the arrays for memory usage 178 _before_gc_usage_array = (MemoryUsage*) NEW_C_HEAP_ARRAY(MemoryUsage, num_pools, mtInternal); 179 _after_gc_usage_array = (MemoryUsage*) NEW_C_HEAP_ARRAY(MemoryUsage, num_pools, mtInternal); 180 _usage_array_size = num_pools; 181 clear(); 182 } 183 184 GCStatInfo::~GCStatInfo() { 185 FREE_C_HEAP_ARRAY(MemoryUsage*, _before_gc_usage_array, mtInternal); 186 FREE_C_HEAP_ARRAY(MemoryUsage*, _after_gc_usage_array, mtInternal); 187 } 188 189 void GCStatInfo::set_gc_usage(int pool_index, MemoryUsage usage, bool before_gc) { 190 MemoryUsage* gc_usage_array; 191 if (before_gc) { 192 gc_usage_array = _before_gc_usage_array; 193 } else { 194 gc_usage_array = _after_gc_usage_array; 195 } 196 gc_usage_array[pool_index] = usage; 197 } 198 199 void GCStatInfo::clear() { 200 _index = 0; 201 _start_time = 0L; 202 _end_time = 0L; 203 size_t len = _usage_array_size * sizeof(MemoryUsage); 204 memset(_before_gc_usage_array, 0, len); 205 memset(_after_gc_usage_array, 0, len); 206 } 207 208 209 GCMemoryManager::GCMemoryManager() : MemoryManager() { 210 _num_collections = 0; 211 _last_gc_stat = NULL; 212 _last_gc_lock = new Mutex(Mutex::leaf, "_last_gc_lock", true); 213 _current_gc_stat = NULL; 214 _num_gc_threads = 1; 215 _notification_enabled = false; 216 } 217 218 GCMemoryManager::~GCMemoryManager() { 219 delete _last_gc_stat; 220 delete _last_gc_lock; 221 delete _current_gc_stat; 222 } 223 224 void GCMemoryManager::initialize_gc_stat_info() { 225 assert(MemoryService::num_memory_pools() > 0, "should have one or more memory pools"); 226 _last_gc_stat = new(ResourceObj::C_HEAP, mtGC) GCStatInfo(MemoryService::num_memory_pools()); 227 _current_gc_stat = new(ResourceObj::C_HEAP, mtGC) GCStatInfo(MemoryService::num_memory_pools()); 228 // tracking concurrent collections we need two objects: one to update, and one to 229 // hold the publicly available "last (completed) gc" information. 230 } 231 232 void GCMemoryManager::gc_begin(bool recordGCBeginTime, bool recordPreGCUsage, 233 bool recordAccumulatedGCTime) { 234 assert(_last_gc_stat != NULL && _current_gc_stat != NULL, "Just checking"); 235 if (recordAccumulatedGCTime) { 236 _accumulated_timer.start(); 237 } 238 // _num_collections now increases in gc_end, to count completed collections 239 if (recordGCBeginTime) { 240 _current_gc_stat->set_index(_num_collections+1); 241 _current_gc_stat->set_start_time(Management::timestamp()); 242 } 243 244 if (recordPreGCUsage) { 245 // Keep memory usage of all memory pools 246 for (int i = 0; i < MemoryService::num_memory_pools(); i++) { 247 MemoryPool* pool = MemoryService::get_memory_pool(i); 248 MemoryUsage usage = pool->get_memory_usage(); 249 _current_gc_stat->set_before_gc_usage(i, usage); 250 #ifndef USDT2 251 HS_DTRACE_PROBE8(hotspot, mem__pool__gc__begin, 252 name(), strlen(name()), 253 pool->name(), strlen(pool->name()), 254 usage.init_size(), usage.used(), 255 usage.committed(), usage.max_size()); 256 #else /* USDT2 */ 257 HOTSPOT_MEM_POOL_GC_BEGIN( 258 (char *) name(), strlen(name()), 259 (char *) pool->name(), strlen(pool->name()), 260 usage.init_size(), usage.used(), 261 usage.committed(), usage.max_size()); 262 #endif /* USDT2 */ 263 } 264 } 265 } 266 267 // A collector MUST, even if it does not complete for some reason, 268 // make a TraceMemoryManagerStats object where countCollection is true, 269 // to ensure the current gc stat is placed in _last_gc_stat. 270 void GCMemoryManager::gc_end(bool recordPostGCUsage, 271 bool recordAccumulatedGCTime, 272 bool recordGCEndTime, bool countCollection, 273 GCCause::Cause cause) { 274 if (recordAccumulatedGCTime) { 275 _accumulated_timer.stop(); 276 } 277 if (recordGCEndTime) { 278 _current_gc_stat->set_end_time(Management::timestamp()); 279 } 280 281 if (recordPostGCUsage) { 282 int i; 283 // keep the last gc statistics for all memory pools 284 for (i = 0; i < MemoryService::num_memory_pools(); i++) { 285 MemoryPool* pool = MemoryService::get_memory_pool(i); 286 MemoryUsage usage = pool->get_memory_usage(); 287 288 #ifndef USDT2 289 HS_DTRACE_PROBE8(hotspot, mem__pool__gc__end, 290 name(), strlen(name()), 291 pool->name(), strlen(pool->name()), 292 usage.init_size(), usage.used(), 293 usage.committed(), usage.max_size()); 294 #else /* USDT2 */ 295 HOTSPOT_MEM_POOL_GC_END( 296 (char *) name(), strlen(name()), 297 (char *) pool->name(), strlen(pool->name()), 298 usage.init_size(), usage.used(), 299 usage.committed(), usage.max_size()); 300 #endif /* USDT2 */ 301 302 _current_gc_stat->set_after_gc_usage(i, usage); 303 } 304 305 // Set last collection usage of the memory pools managed by this collector 306 for (i = 0; i < num_memory_pools(); i++) { 307 MemoryPool* pool = get_memory_pool(i); 308 MemoryUsage usage = pool->get_memory_usage(); 309 310 // Compare with GC usage threshold 311 pool->set_last_collection_usage(usage); 312 LowMemoryDetector::detect_after_gc_memory(pool); 313 } 314 } 315 316 if (countCollection) { 317 _num_collections++; 318 // alternately update two objects making one public when complete 319 { 320 MutexLockerEx ml(_last_gc_lock, Mutex::_no_safepoint_check_flag); 321 GCStatInfo *tmp = _last_gc_stat; 322 _last_gc_stat = _current_gc_stat; 323 _current_gc_stat = tmp; 324 // reset the current stat for diagnosability purposes 325 _current_gc_stat->clear(); 326 } 327 328 if (is_notification_enabled()) { 329 bool isMajorGC = this == MemoryService::get_major_gc_manager(); 330 GCNotifier::pushNotification(this, isMajorGC ? "end of major GC" : "end of minor GC", 331 GCCause::to_string(cause)); 332 } 333 } 334 } 335 336 size_t GCMemoryManager::get_last_gc_stat(GCStatInfo* dest) { 337 MutexLockerEx ml(_last_gc_lock, Mutex::_no_safepoint_check_flag); 338 if (_last_gc_stat->gc_index() != 0) { 339 dest->set_index(_last_gc_stat->gc_index()); 340 dest->set_start_time(_last_gc_stat->start_time()); 341 dest->set_end_time(_last_gc_stat->end_time()); 342 assert(dest->usage_array_size() == _last_gc_stat->usage_array_size(), 343 "Must have same array size"); 344 size_t len = dest->usage_array_size() * sizeof(MemoryUsage); 345 memcpy(dest->before_gc_usage_array(), _last_gc_stat->before_gc_usage_array(), len); 346 memcpy(dest->after_gc_usage_array(), _last_gc_stat->after_gc_usage_array(), len); 347 } 348 return _last_gc_stat->gc_index(); 349 }