7195789: NPG: assert(used + free == capacity) failed: Accounting is wrong
authorjmasa
Tue, 04 Sep 2012 16:20:28 -0700
changeset 13733 e41e23ae6758
parent 13732 a9865f5514fc
child 13734 4b74094540f3
child 13744 631fe815def5
7195789: NPG: assert(used + free == capacity) failed: Accounting is wrong Reviewed-by: coleenp, jcoomes
hotspot/src/share/vm/memory/metaspace.cpp
hotspot/src/share/vm/memory/metaspace.hpp
hotspot/src/share/vm/memory/metaspaceCounters.cpp
--- 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);
 }