mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 14:54:52 +02:00
6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
Management code enabled for use by a concurrent collector. Reviewed-by: mchung, ysr
This commit is contained in:
parent
428d02d5d7
commit
5fb46fd5a8
9 changed files with 435 additions and 79 deletions
|
@ -166,17 +166,6 @@ GCStatInfo::~GCStatInfo() {
|
|||
FREE_C_HEAP_ARRAY(MemoryUsage*, _after_gc_usage_array);
|
||||
}
|
||||
|
||||
void GCStatInfo::copy_stat(GCStatInfo* stat) {
|
||||
set_index(stat->gc_index());
|
||||
set_start_time(stat->start_time());
|
||||
set_end_time(stat->end_time());
|
||||
assert(_usage_array_size == stat->usage_array_size(), "Must have same array size");
|
||||
for (int i = 0; i < _usage_array_size; i++) {
|
||||
set_before_gc_usage(i, stat->before_gc_usage_for_pool(i));
|
||||
set_after_gc_usage(i, stat->after_gc_usage_for_pool(i));
|
||||
}
|
||||
}
|
||||
|
||||
void GCStatInfo::set_gc_usage(int pool_index, MemoryUsage usage, bool before_gc) {
|
||||
MemoryUsage* gc_usage_array;
|
||||
if (before_gc) {
|
||||
|
@ -187,67 +176,129 @@ void GCStatInfo::set_gc_usage(int pool_index, MemoryUsage usage, bool before_gc)
|
|||
gc_usage_array[pool_index] = usage;
|
||||
}
|
||||
|
||||
void GCStatInfo::clear() {
|
||||
_index = 0;
|
||||
_start_time = 0L;
|
||||
_end_time = 0L;
|
||||
size_t len = _usage_array_size * sizeof(MemoryUsage);
|
||||
memset(_before_gc_usage_array, 0, len);
|
||||
memset(_after_gc_usage_array, 0, len);
|
||||
}
|
||||
|
||||
|
||||
GCMemoryManager::GCMemoryManager() : MemoryManager() {
|
||||
_num_collections = 0;
|
||||
_last_gc_stat = NULL;
|
||||
_last_gc_lock = new Mutex(Mutex::leaf, "_last_gc_lock", true);
|
||||
_current_gc_stat = NULL;
|
||||
_num_gc_threads = 1;
|
||||
}
|
||||
|
||||
GCMemoryManager::~GCMemoryManager() {
|
||||
delete _last_gc_stat;
|
||||
delete _last_gc_lock;
|
||||
delete _current_gc_stat;
|
||||
}
|
||||
|
||||
void GCMemoryManager::initialize_gc_stat_info() {
|
||||
assert(MemoryService::num_memory_pools() > 0, "should have one or more memory pools");
|
||||
_last_gc_stat = new GCStatInfo(MemoryService::num_memory_pools());
|
||||
_current_gc_stat = new GCStatInfo(MemoryService::num_memory_pools());
|
||||
// tracking concurrent collections we need two objects: one to update, and one to
|
||||
// hold the publicly available "last (completed) gc" information.
|
||||
}
|
||||
|
||||
void GCMemoryManager::gc_begin() {
|
||||
assert(_last_gc_stat != NULL, "Just checking");
|
||||
_accumulated_timer.start();
|
||||
_num_collections++;
|
||||
_last_gc_stat->set_index(_num_collections);
|
||||
_last_gc_stat->set_start_time(Management::timestamp());
|
||||
void GCMemoryManager::gc_begin(bool recordGCBeginTime, bool recordPreGCUsage,
|
||||
bool recordAccumulatedGCTime) {
|
||||
assert(_last_gc_stat != NULL && _current_gc_stat != NULL, "Just checking");
|
||||
if (recordAccumulatedGCTime) {
|
||||
_accumulated_timer.start();
|
||||
}
|
||||
// _num_collections now increases in gc_end, to count completed collections
|
||||
if (recordGCBeginTime) {
|
||||
_current_gc_stat->set_index(_num_collections+1);
|
||||
_current_gc_stat->set_start_time(Management::timestamp());
|
||||
}
|
||||
|
||||
// Keep memory usage of all memory pools
|
||||
for (int i = 0; i < MemoryService::num_memory_pools(); i++) {
|
||||
MemoryPool* pool = MemoryService::get_memory_pool(i);
|
||||
MemoryUsage usage = pool->get_memory_usage();
|
||||
_last_gc_stat->set_before_gc_usage(i, usage);
|
||||
HS_DTRACE_PROBE8(hotspot, mem__pool__gc__begin,
|
||||
name(), strlen(name()),
|
||||
pool->name(), strlen(pool->name()),
|
||||
usage.init_size(), usage.used(),
|
||||
usage.committed(), usage.max_size());
|
||||
if (recordPreGCUsage) {
|
||||
// Keep memory usage of all memory pools
|
||||
for (int i = 0; i < MemoryService::num_memory_pools(); i++) {
|
||||
MemoryPool* pool = MemoryService::get_memory_pool(i);
|
||||
MemoryUsage usage = pool->get_memory_usage();
|
||||
_current_gc_stat->set_before_gc_usage(i, usage);
|
||||
HS_DTRACE_PROBE8(hotspot, mem__pool__gc__begin,
|
||||
name(), strlen(name()),
|
||||
pool->name(), strlen(pool->name()),
|
||||
usage.init_size(), usage.used(),
|
||||
usage.committed(), usage.max_size());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GCMemoryManager::gc_end() {
|
||||
_accumulated_timer.stop();
|
||||
_last_gc_stat->set_end_time(Management::timestamp());
|
||||
|
||||
int i;
|
||||
// keep the last gc statistics for all memory pools
|
||||
for (i = 0; i < MemoryService::num_memory_pools(); i++) {
|
||||
MemoryPool* pool = MemoryService::get_memory_pool(i);
|
||||
MemoryUsage usage = pool->get_memory_usage();
|
||||
|
||||
HS_DTRACE_PROBE8(hotspot, mem__pool__gc__end,
|
||||
name(), strlen(name()),
|
||||
pool->name(), strlen(pool->name()),
|
||||
usage.init_size(), usage.used(),
|
||||
usage.committed(), usage.max_size());
|
||||
|
||||
_last_gc_stat->set_after_gc_usage(i, usage);
|
||||
// A collector MUST, even if it does not complete for some reason,
|
||||
// make a TraceMemoryManagerStats object where countCollection is true,
|
||||
// to ensure the current gc stat is placed in _last_gc_stat.
|
||||
void GCMemoryManager::gc_end(bool recordPostGCUsage,
|
||||
bool recordAccumulatedGCTime,
|
||||
bool recordGCEndTime, bool countCollection) {
|
||||
if (recordAccumulatedGCTime) {
|
||||
_accumulated_timer.stop();
|
||||
}
|
||||
if (recordGCEndTime) {
|
||||
_current_gc_stat->set_end_time(Management::timestamp());
|
||||
}
|
||||
|
||||
// Set last collection usage of the memory pools managed by this collector
|
||||
for (i = 0; i < num_memory_pools(); i++) {
|
||||
MemoryPool* pool = get_memory_pool(i);
|
||||
MemoryUsage usage = pool->get_memory_usage();
|
||||
if (recordPostGCUsage) {
|
||||
int i;
|
||||
// keep the last gc statistics for all memory pools
|
||||
for (i = 0; i < MemoryService::num_memory_pools(); i++) {
|
||||
MemoryPool* pool = MemoryService::get_memory_pool(i);
|
||||
MemoryUsage usage = pool->get_memory_usage();
|
||||
|
||||
// Compare with GC usage threshold
|
||||
pool->set_last_collection_usage(usage);
|
||||
LowMemoryDetector::detect_after_gc_memory(pool);
|
||||
HS_DTRACE_PROBE8(hotspot, mem__pool__gc__end,
|
||||
name(), strlen(name()),
|
||||
pool->name(), strlen(pool->name()),
|
||||
usage.init_size(), usage.used(),
|
||||
usage.committed(), usage.max_size());
|
||||
|
||||
_current_gc_stat->set_after_gc_usage(i, usage);
|
||||
}
|
||||
|
||||
// Set last collection usage of the memory pools managed by this collector
|
||||
for (i = 0; i < num_memory_pools(); i++) {
|
||||
MemoryPool* pool = get_memory_pool(i);
|
||||
MemoryUsage usage = pool->get_memory_usage();
|
||||
|
||||
// Compare with GC usage threshold
|
||||
pool->set_last_collection_usage(usage);
|
||||
LowMemoryDetector::detect_after_gc_memory(pool);
|
||||
}
|
||||
}
|
||||
if (countCollection) {
|
||||
_num_collections++;
|
||||
// alternately update two objects making one public when complete
|
||||
{
|
||||
MutexLockerEx ml(_last_gc_lock, Mutex::_no_safepoint_check_flag);
|
||||
GCStatInfo *tmp = _last_gc_stat;
|
||||
_last_gc_stat = _current_gc_stat;
|
||||
_current_gc_stat = tmp;
|
||||
// reset the current stat for diagnosability purposes
|
||||
_current_gc_stat->clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
size_t GCMemoryManager::get_last_gc_stat(GCStatInfo* dest) {
|
||||
MutexLockerEx ml(_last_gc_lock, Mutex::_no_safepoint_check_flag);
|
||||
if (_last_gc_stat->gc_index() != 0) {
|
||||
dest->set_index(_last_gc_stat->gc_index());
|
||||
dest->set_start_time(_last_gc_stat->start_time());
|
||||
dest->set_end_time(_last_gc_stat->end_time());
|
||||
assert(dest->usage_array_size() == _last_gc_stat->usage_array_size(),
|
||||
"Must have same array size");
|
||||
size_t len = dest->usage_array_size() * sizeof(MemoryUsage);
|
||||
memcpy(dest->before_gc_usage_array(), _last_gc_stat->before_gc_usage_array(), len);
|
||||
memcpy(dest->after_gc_usage_array(), _last_gc_stat->after_gc_usage_array(), len);
|
||||
}
|
||||
return _last_gc_stat->gc_index();
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue