7195789: NPG: assert(used + free == capacity) failed: Accounting is wrong
Reviewed-by: coleenp, jcoomes
--- a/hotspot/src/share/vm/memory/metaspace.cpp Tue Sep 04 18:01:20 2012 -0700
+++ b/hotspot/src/share/vm/memory/metaspace.cpp Tue Sep 04 16:20:28 2012 -0700
@@ -2541,7 +2541,22 @@
// 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 @@
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.
--- a/hotspot/src/share/vm/memory/metaspace.hpp Tue Sep 04 18:01:20 2012 -0700
+++ b/hotspot/src/share/vm/memory/metaspace.hpp Tue Sep 04 16:20:28 2012 -0700
@@ -149,6 +149,10 @@
// 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 @@
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
--- a/hotspot/src/share/vm/memory/metaspaceCounters.cpp Tue Sep 04 18:01:20 2012 -0700
+++ b/hotspot/src/share/vm/memory/metaspaceCounters.cpp Tue Sep 04 16:20:28 2012 -0700
@@ -35,7 +35,7 @@
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_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);
}