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
--- a/hotspot/src/share/vm/services/memoryManager.cpp Mon Nov 21 07:47:34 2011 +0100
+++ b/hotspot/src/share/vm/services/memoryManager.cpp Mon Nov 21 09:24:56 2011 -0800
@@ -168,10 +168,8 @@
// initialize the arrays for memory usage
_before_gc_usage_array = (MemoryUsage*) NEW_C_HEAP_ARRAY(MemoryUsage, num_pools);
_after_gc_usage_array = (MemoryUsage*) NEW_C_HEAP_ARRAY(MemoryUsage, num_pools);
- size_t len = num_pools * sizeof(MemoryUsage);
- memset(_before_gc_usage_array, 0, len);
- memset(_after_gc_usage_array, 0, len);
_usage_array_size = num_pools;
+ clear();
}
GCStatInfo::~GCStatInfo() {
@@ -304,12 +302,8 @@
pool->set_last_collection_usage(usage);
LowMemoryDetector::detect_after_gc_memory(pool);
}
- if(is_notification_enabled()) {
- bool isMajorGC = this == MemoryService::get_major_gc_manager();
- GCNotifier::pushNotification(this, isMajorGC ? "end of major GC" : "end of minor GC",
- GCCause::to_string(cause));
- }
}
+
if (countCollection) {
_num_collections++;
// alternately update two objects making one public when complete
@@ -321,6 +315,12 @@
// reset the current stat for diagnosability purposes
_current_gc_stat->clear();
}
+
+ if (is_notification_enabled()) {
+ bool isMajorGC = this == MemoryService::get_major_gc_manager();
+ GCNotifier::pushNotification(this, isMajorGC ? "end of major GC" : "end of minor GC",
+ GCCause::to_string(cause));
+ }
}
}