comparison src/share/vm/services/memoryManager.cpp @ 4092:b5a5f30c483d

7110173: GCNotifier::pushNotification publishes stale data. Summary: GCNotifier::pushNotification() references GCMemoryManager::_last_gc_stat but is called from GCMemoryManager::gc_end() before GCMemoryManager::_last_gc_stat is set up using the values in GCMemoryManager::_current_gc_stat. As a result the GC notification code accesses unitialized or stale data. Move the notification call after GCMemoryManager::_las_gc_stat is set, but inside the same if-block. Reviewed-by: poonam, dholmes, fparain, mchung
author johnc
date Mon, 21 Nov 2011 09:24:56 -0800
parents 436b4a3231bf
children bf864f701a4a
comparison
equal deleted inserted replaced
4091:d06a2d7fcd5b 4092:b5a5f30c483d
166 166
167 GCStatInfo::GCStatInfo(int num_pools) { 167 GCStatInfo::GCStatInfo(int num_pools) {
168 // initialize the arrays for memory usage 168 // initialize the arrays for memory usage
169 _before_gc_usage_array = (MemoryUsage*) NEW_C_HEAP_ARRAY(MemoryUsage, num_pools); 169 _before_gc_usage_array = (MemoryUsage*) NEW_C_HEAP_ARRAY(MemoryUsage, num_pools);
170 _after_gc_usage_array = (MemoryUsage*) NEW_C_HEAP_ARRAY(MemoryUsage, num_pools); 170 _after_gc_usage_array = (MemoryUsage*) NEW_C_HEAP_ARRAY(MemoryUsage, num_pools);
171 size_t len = num_pools * sizeof(MemoryUsage);
172 memset(_before_gc_usage_array, 0, len);
173 memset(_after_gc_usage_array, 0, len);
174 _usage_array_size = num_pools; 171 _usage_array_size = num_pools;
172 clear();
175 } 173 }
176 174
177 GCStatInfo::~GCStatInfo() { 175 GCStatInfo::~GCStatInfo() {
178 FREE_C_HEAP_ARRAY(MemoryUsage*, _before_gc_usage_array); 176 FREE_C_HEAP_ARRAY(MemoryUsage*, _before_gc_usage_array);
179 FREE_C_HEAP_ARRAY(MemoryUsage*, _after_gc_usage_array); 177 FREE_C_HEAP_ARRAY(MemoryUsage*, _after_gc_usage_array);
302 300
303 // Compare with GC usage threshold 301 // Compare with GC usage threshold
304 pool->set_last_collection_usage(usage); 302 pool->set_last_collection_usage(usage);
305 LowMemoryDetector::detect_after_gc_memory(pool); 303 LowMemoryDetector::detect_after_gc_memory(pool);
306 } 304 }
307 if(is_notification_enabled()) { 305 }
308 bool isMajorGC = this == MemoryService::get_major_gc_manager(); 306
309 GCNotifier::pushNotification(this, isMajorGC ? "end of major GC" : "end of minor GC",
310 GCCause::to_string(cause));
311 }
312 }
313 if (countCollection) { 307 if (countCollection) {
314 _num_collections++; 308 _num_collections++;
315 // alternately update two objects making one public when complete 309 // alternately update two objects making one public when complete
316 { 310 {
317 MutexLockerEx ml(_last_gc_lock, Mutex::_no_safepoint_check_flag); 311 MutexLockerEx ml(_last_gc_lock, Mutex::_no_safepoint_check_flag);
318 GCStatInfo *tmp = _last_gc_stat; 312 GCStatInfo *tmp = _last_gc_stat;
319 _last_gc_stat = _current_gc_stat; 313 _last_gc_stat = _current_gc_stat;
320 _current_gc_stat = tmp; 314 _current_gc_stat = tmp;
321 // reset the current stat for diagnosability purposes 315 // reset the current stat for diagnosability purposes
322 _current_gc_stat->clear(); 316 _current_gc_stat->clear();
317 }
318
319 if (is_notification_enabled()) {
320 bool isMajorGC = this == MemoryService::get_major_gc_manager();
321 GCNotifier::pushNotification(this, isMajorGC ? "end of major GC" : "end of minor GC",
322 GCCause::to_string(cause));
323 } 323 }
324 } 324 }
325 } 325 }
326 326
327 size_t GCMemoryManager::get_last_gc_stat(GCStatInfo* dest) { 327 size_t GCMemoryManager::get_last_gc_stat(GCStatInfo* dest) {