From 9c9d9209c7762eca6d244b1989ef5a5c885cb93f Mon Sep 17 00:00:00 2001 From: jmasa Date: Tue, 4 Sep 2012 16:20:28 -0700 Subject: [PATCH] 7195789: NPG: assert(used + free == capacity) failed: Accounting is wrong Reviewed-by: coleenp, jcoomes --- src/share/vm/memory/metaspace.cpp | 21 ++++++++++++++++++--- src/share/vm/memory/metaspace.hpp | 9 +++++++++ src/share/vm/memory/metaspaceCounters.cpp | 4 ++-- 3 files changed, 29 insertions(+), 5 deletions(-) diff --git a/src/share/vm/memory/metaspace.cpp b/src/share/vm/memory/metaspace.cpp index cea821854..97ac77e83 100644 --- a/src/share/vm/memory/metaspace.cpp +++ b/src/share/vm/memory/metaspace.cpp @@ -2541,7 +2541,22 @@ void SpaceManager::mangle_freed_chunks() { // MetaspaceAux +size_t MetaspaceAux::used_in_bytes_unsafe(Metaspace::MetadataType mdtype) { + size_t used = 0; + ClassLoaderDataGraphMetaspaceIterator iter; + while (iter.repeat()) { + Metaspace* msp = iter.get_next(); + // Sum allocation_total for each metaspace + if (msp != NULL) { + used += msp->used_words(mdtype); + } + } + return used * BytesPerWord; +} + size_t MetaspaceAux::used_in_bytes(Metaspace::MetadataType mdtype) { + assert(SafepointSynchronize::is_at_safepoint(), + "Consistency checks require being at a safepoint"); size_t used = 0; #ifdef ASSERT size_t free = 0; @@ -2646,15 +2661,15 @@ void MetaspaceAux::print_on(outputStream* out) { out->print_cr(" Metaspace total " SIZE_FORMAT "K, used " SIZE_FORMAT "K," " reserved " SIZE_FORMAT "K", - capacity_in_bytes()/K, used_in_bytes()/K, reserved_in_bytes()/K); + capacity_in_bytes()/K, used_in_bytes_unsafe()/K, reserved_in_bytes()/K); out->print_cr(" data space " SIZE_FORMAT "K, used " SIZE_FORMAT "K," " reserved " SIZE_FORMAT "K", - capacity_in_bytes(nct)/K, used_in_bytes(nct)/K, reserved_in_bytes(nct)/K); + capacity_in_bytes(nct)/K, used_in_bytes_unsafe(nct)/K, reserved_in_bytes(nct)/K); out->print_cr(" class space " SIZE_FORMAT "K, used " SIZE_FORMAT "K," " reserved " SIZE_FORMAT "K", - capacity_in_bytes(ct)/K, used_in_bytes(ct)/K, reserved_in_bytes(ct)/K); + capacity_in_bytes(ct)/K, used_in_bytes_unsafe(ct)/K, reserved_in_bytes(ct)/K); } // Print information for class space and data space separately. diff --git a/src/share/vm/memory/metaspace.hpp b/src/share/vm/memory/metaspace.hpp index dd516e87f..73580d100 100644 --- a/src/share/vm/memory/metaspace.hpp +++ b/src/share/vm/memory/metaspace.hpp @@ -149,6 +149,10 @@ class MetaspaceAux : AllStatic { // Statistics for class space and data space in metaspace. static size_t used_in_bytes(Metaspace::MetadataType mdtype); + // Same as used_in_bytes() without the consistency checking. + // Use this version if not at a safepoint (so consistency is + // not necessarily expected). + static size_t used_in_bytes_unsafe(Metaspace::MetadataType mdtype); static size_t free_in_bytes(Metaspace::MetadataType mdtype); static size_t capacity_in_bytes(Metaspace::MetadataType mdtype); static size_t reserved_in_bytes(Metaspace::MetadataType mdtype); @@ -163,6 +167,11 @@ class MetaspaceAux : AllStatic { used_in_bytes(Metaspace::NonClassType); } + static size_t used_in_bytes_unsafe() { + return used_in_bytes_unsafe(Metaspace::ClassType) + + used_in_bytes_unsafe(Metaspace::NonClassType); + } + // Total of available space in all Metaspaces // Total of capacity allocated to all Metaspaces. This includes // space in Metachunks not yet allocated and in the Metachunk diff --git a/src/share/vm/memory/metaspaceCounters.cpp b/src/share/vm/memory/metaspaceCounters.cpp index d8237f734..d092d19a8 100644 --- a/src/share/vm/memory/metaspaceCounters.cpp +++ b/src/share/vm/memory/metaspaceCounters.cpp @@ -35,7 +35,7 @@ MetaspaceCounters::MetaspaceCounters() { size_t min_capacity = MetaspaceAux::min_chunk_size(); size_t max_capacity = MetaspaceAux::reserved_in_bytes(); size_t curr_capacity = MetaspaceAux::capacity_in_bytes(); - size_t used = MetaspaceAux::used_in_bytes(); + size_t used = MetaspaceAux::used_in_bytes_unsafe(); initialize(min_capacity, max_capacity, curr_capacity, used); } @@ -131,7 +131,7 @@ void MetaspaceCounters::update_capacity() { void MetaspaceCounters::update_used() { assert(UsePerfData, "Should not be called unless being used"); - size_t used_in_bytes = MetaspaceAux::used_in_bytes(); + size_t used_in_bytes = MetaspaceAux::used_in_bytes_unsafe(); _used->set_value(used_in_bytes); } -- GitLab