8219524: Shenandoah misreports "committed" size in MemoryMXBean
authorshade
Thu, 21 Feb 2019 15:52:42 +0100
changeset 53873 5cf6623b1283
parent 53872 cc9359f8c563
child 53874 b2fb6f782d84
8219524: Shenandoah misreports "committed" size in MemoryMXBean Reviewed-by: rkennke, zgu
src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp
src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp
src/hotspot/share/gc/shenandoah/shenandoahMemoryPool.cpp
test/hotspot/jtreg/gc/shenandoah/mxbeans/TestMemoryMXBeans.java
--- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp	Thu Feb 21 14:16:44 2019 +0100
+++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp	Thu Feb 21 15:52:42 2019 +0100
@@ -2639,6 +2639,10 @@
   return memory_pools;
 }
 
+MemoryUsage ShenandoahHeap::memory_usage() {
+  return _memory_pool->get_memory_usage();
+}
+
 void ShenandoahHeap::enter_evacuation() {
   _oom_evac_handler.enter_evacuation();
 }
--- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp	Thu Feb 21 14:16:44 2019 +0100
+++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp	Thu Feb 21 15:52:42 2019 +0100
@@ -511,6 +511,7 @@
 
   GrowableArray<GCMemoryManager*> memory_managers();
   GrowableArray<MemoryPool*> memory_pools();
+  MemoryUsage memory_usage();
   GCTracer* tracer();
   GCTimer* gc_timer() const;
   CollectorPolicy* collector_policy() const;
--- a/src/hotspot/share/gc/shenandoah/shenandoahMemoryPool.cpp	Thu Feb 21 14:16:44 2019 +0100
+++ b/src/hotspot/share/gc/shenandoah/shenandoahMemoryPool.cpp	Thu Feb 21 15:52:42 2019 +0100
@@ -26,7 +26,7 @@
 
 ShenandoahMemoryPool::ShenandoahMemoryPool(ShenandoahHeap* heap) :
         CollectedMemoryPool("Shenandoah",
-                            heap->capacity(),
+                            heap->initial_capacity(),
                             heap->max_capacity(),
                             true /* support_usage_threshold */),
                             _heap(heap) {}
@@ -37,9 +37,15 @@
   size_t used      = used_in_bytes();
   size_t committed = _heap->committed();
 
+  // These asserts can never fail: max is stable, and all updates to other values never overflow max.
   assert(initial <= max,    "initial: "   SIZE_FORMAT ", max: "       SIZE_FORMAT, initial,   max);
   assert(used <= max,       "used: "      SIZE_FORMAT ", max: "       SIZE_FORMAT, used,      max);
   assert(committed <= max,  "committed: " SIZE_FORMAT ", max: "       SIZE_FORMAT, committed, max);
+
+  // Committed and used are updated concurrently and independently. They can momentarily break
+  // the assert below, which would also fail in downstream code. To avoid that, adjust values
+  // to make sense under the race. See JDK-8207200.
+  committed = MAX2(used, committed);
   assert(used <= committed, "used: "      SIZE_FORMAT ", committed: " SIZE_FORMAT, used,      committed);
 
   return MemoryUsage(initial, used, committed, max);
--- a/test/hotspot/jtreg/gc/shenandoah/mxbeans/TestMemoryMXBeans.java	Thu Feb 21 14:16:44 2019 +0100
+++ b/test/hotspot/jtreg/gc/shenandoah/mxbeans/TestMemoryMXBeans.java	Thu Feb 21 15:52:42 2019 +0100
@@ -52,8 +52,10 @@
     public static void testMemoryBean(long initSize, long maxSize) {
         MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean();
         long heapInit = memoryMXBean.getHeapMemoryUsage().getInit();
+        long heapCommitted = memoryMXBean.getHeapMemoryUsage().getCommitted();
         long heapMax = memoryMXBean.getHeapMemoryUsage().getMax();
         long nonHeapInit = memoryMXBean.getNonHeapMemoryUsage().getInit();
+        long nonHeapCommitted = memoryMXBean.getNonHeapMemoryUsage().getCommitted();
         long nonHeapMax = memoryMXBean.getNonHeapMemoryUsage().getMax();
 
         if (initSize > 0 && heapInit != initSize) {
@@ -62,5 +64,9 @@
         if (maxSize > 0 && heapMax != maxSize) {
             throw new IllegalStateException("Max heap size is wrong: " + heapMax + " vs " + maxSize);
         }
+        if (initSize > 0 && maxSize > 0 && initSize != maxSize && heapCommitted == heapMax) {
+            throw new IllegalStateException("Init committed heap size is wrong: " + heapCommitted +
+                                            " (init: " + initSize + ", max: " + maxSize + ")");
+        }
     }
 }