8218049: Survivor MemoryMXBean used() size granularity is region based
authorsangheki
Mon, 08 Apr 2019 12:15:40 -0700
changeset 54467 0c5d713cf43f
parent 54466 58751415d5f8
child 54468 b02d1d829b09
8218049: Survivor MemoryMXBean used() size granularity is region based Reviewed-by: tschatzl, kbarrett
src/hotspot/share/gc/g1/g1CollectedHeap.cpp
src/hotspot/share/gc/g1/g1CollectedHeap.hpp
src/hotspot/share/gc/g1/g1EdenRegions.hpp
src/hotspot/share/gc/g1/g1MonitoringSupport.cpp
src/hotspot/share/gc/g1/g1MonitoringSupport.hpp
src/hotspot/share/gc/g1/g1SurvivorRegions.cpp
src/hotspot/share/gc/g1/g1SurvivorRegions.hpp
src/hotspot/share/gc/g1/vmStructs_g1.hpp
test/hotspot/jtreg/ProblemList.txt
test/hotspot/jtreg/gc/survivorAlignment/TestAllocationInEden.java
test/hotspot/jtreg/gc/survivorAlignment/TestPromotionFromEdenToTenured.java
test/hotspot/jtreg/gc/survivorAlignment/TestPromotionFromSurvivorToTenuredAfterFullGC.java
test/hotspot/jtreg/gc/survivorAlignment/TestPromotionFromSurvivorToTenuredAfterMinorGC.java
test/hotspot/jtreg/gc/survivorAlignment/TestPromotionLABLargeSurvivorAlignment.java
test/hotspot/jtreg/gc/survivorAlignment/TestPromotionToSurvivor.java
--- a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp	Mon Apr 08 21:01:17 2019 +0200
+++ b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp	Mon Apr 08 12:15:40 2019 -0700
@@ -2500,8 +2500,8 @@
 
 G1HeapSummary G1CollectedHeap::create_g1_heap_summary() {
 
-  size_t eden_used_bytes = heap()->eden_regions_count() * HeapRegion::GrainBytes;
-  size_t survivor_used_bytes = heap()->survivor_regions_count() * HeapRegion::GrainBytes;
+  size_t eden_used_bytes = _eden.used_bytes();
+  size_t survivor_used_bytes = _survivor.used_bytes();
   size_t heap_used = Heap_lock->owned_by_self() ? used() : used_unlocked();
 
   size_t eden_capacity_bytes =
@@ -4585,7 +4585,9 @@
 
   collection_set()->add_eden_region(alloc_region);
   increase_used(allocated_bytes);
+  _eden.add_used_bytes(allocated_bytes);
   _hr_printer.retire(alloc_region);
+
   // We update the eden sizes here, when the region is retired,
   // instead of when it's allocated, since this is the point that its
   // used space has been recorded in _summary_bytes_used.
@@ -4642,6 +4644,9 @@
   policy()->record_bytes_copied_during_gc(allocated_bytes);
   if (dest.is_old()) {
     old_set_add(alloc_region);
+  } else {
+    assert(dest.is_young(), "Retiring alloc region should be young(%d)", dest.value());
+    _survivor.add_used_bytes(allocated_bytes);
   }
 
   bool const during_im = collector_state()->in_initial_mark_gc();
--- a/src/hotspot/share/gc/g1/g1CollectedHeap.hpp	Mon Apr 08 21:01:17 2019 +0200
+++ b/src/hotspot/share/gc/g1/g1CollectedHeap.hpp	Mon Apr 08 12:15:40 2019 -0700
@@ -205,7 +205,7 @@
 
   // Outside of GC pauses, the number of bytes used in all regions other
   // than the current allocation region(s).
-  size_t _summary_bytes_used;
+  volatile size_t _summary_bytes_used;
 
   void increase_used(size_t bytes);
   void decrease_used(size_t bytes);
@@ -1258,6 +1258,8 @@
 
   uint eden_regions_count() const { return _eden.length(); }
   uint survivor_regions_count() const { return _survivor.length(); }
+  size_t eden_regions_used_bytes() const { return _eden.used_bytes(); }
+  size_t survivor_regions_used_bytes() const { return _survivor.used_bytes(); }
   uint young_regions_count() const { return _eden.length() + _survivor.length(); }
   uint old_regions_count() const { return _old_set.length(); }
   uint archive_regions_count() const { return _archive_set.length(); }
--- a/src/hotspot/share/gc/g1/g1EdenRegions.hpp	Mon Apr 08 21:01:17 2019 +0200
+++ b/src/hotspot/share/gc/g1/g1EdenRegions.hpp	Mon Apr 08 12:15:40 2019 -0700
@@ -31,19 +31,28 @@
 
 class G1EdenRegions {
 private:
-  int _length;
+  int    _length;
+  // Sum of used bytes from all retired eden regions.
+  // I.e. updated when mutator regions are retired.
+  volatile size_t _used_bytes;
 
 public:
-  G1EdenRegions() : _length(0) {}
+  G1EdenRegions() : _length(0), _used_bytes(0) { }
 
   void add(HeapRegion* hr) {
     assert(!hr->is_eden(), "should not already be set");
     _length++;
   }
 
-  void clear() { _length = 0; }
+  void clear() { _length = 0; _used_bytes = 0; }
 
   uint length() const { return _length; }
+
+  size_t used_bytes() const { return _used_bytes; }
+
+  void add_used_bytes(size_t used_bytes) {
+    _used_bytes += used_bytes;
+  }
 };
 
 #endif // SHARE_GC_G1_G1EDENREGIONS_HPP
--- a/src/hotspot/share/gc/g1/g1MonitoringSupport.cpp	Mon Apr 08 21:01:17 2019 +0200
+++ b/src/hotspot/share/gc/g1/g1MonitoringSupport.cpp	Mon Apr 08 12:15:40 2019 -0700
@@ -228,23 +228,25 @@
   MutexLockerEx x(MonitoringSupport_lock, Mutex::_no_safepoint_check_flag);
   // Recalculate all the sizes from scratch.
 
-  uint young_list_length = _g1h->young_regions_count();
+  // This never includes used bytes of current allocating heap region.
+  _overall_used = _g1h->used_unlocked();
+  _eden_space_used = _g1h->eden_regions_used_bytes();
+  _survivor_space_used = _g1h->survivor_regions_used_bytes();
+
+  // _overall_used and _eden_space_used are obtained concurrently so
+  // may be inconsistent with each other. To prevent _old_gen_used going negative,
+  // use smaller value to substract.
+  _old_gen_used = _overall_used - MIN2(_overall_used, _eden_space_used + _survivor_space_used);
+
   uint survivor_list_length = _g1h->survivor_regions_count();
-  assert(young_list_length >= survivor_list_length, "invariant");
-  uint eden_list_length = young_list_length - survivor_list_length;
   // Max length includes any potential extensions to the young gen
   // we'll do when the GC locker is active.
   uint young_list_max_length = _g1h->policy()->young_list_max_length();
   assert(young_list_max_length >= survivor_list_length, "invariant");
   uint eden_list_max_length = young_list_max_length - survivor_list_length;
 
-  _overall_used = _g1h->used_unlocked();
-  _eden_space_used = (size_t) eden_list_length * HeapRegion::GrainBytes;
-  _survivor_space_used = (size_t) survivor_list_length * HeapRegion::GrainBytes;
-  _old_gen_used = subtract_up_to_zero(_overall_used, _eden_space_used + _survivor_space_used);
-
   // First calculate the committed sizes that can be calculated independently.
-  _survivor_space_committed = _survivor_space_used;
+  _survivor_space_committed = survivor_list_length * HeapRegion::GrainBytes;
   _old_gen_committed = HeapRegion::align_up_to_region_byte_size(_old_gen_used);
 
   // Next, start with the overall committed size.
@@ -274,11 +276,15 @@
   // Somewhat defensive: cap the eden used size to make sure it
   // never exceeds the committed size.
   _eden_space_used = MIN2(_eden_space_used, _eden_space_committed);
-  // _survivor_committed and _old_committed are calculated in terms of
-  // the corresponding _*_used value, so the next two conditions
-  // should hold.
-  assert(_survivor_space_used <= _survivor_space_committed, "post-condition");
-  assert(_old_gen_used <= _old_gen_committed, "post-condition");
+  // _survivor_space_used is calculated during a safepoint and _survivor_space_committed
+  // is calculated from survivor region count * heap region size.
+  assert(_survivor_space_used <= _survivor_space_committed, "Survivor used bytes(" SIZE_FORMAT
+         ") should be less than or equal to survivor committed(" SIZE_FORMAT ")",
+         _survivor_space_used, _survivor_space_committed);
+  // _old_gen_committed is calculated in terms of _old_gen_used value.
+  assert(_old_gen_used <= _old_gen_committed, "Old gen used bytes(" SIZE_FORMAT
+         ") should be less than or equal to old gen committed(" SIZE_FORMAT ")",
+         _old_gen_used, _old_gen_committed);
 }
 
 void G1MonitoringSupport::update_sizes() {
--- a/src/hotspot/share/gc/g1/g1MonitoringSupport.hpp	Mon Apr 08 21:01:17 2019 +0200
+++ b/src/hotspot/share/gc/g1/g1MonitoringSupport.hpp	Mon Apr 08 12:15:40 2019 -0700
@@ -174,21 +174,6 @@
 
   size_t _old_gen_used;
 
-  // It returns x - y if x > y, 0 otherwise.
-  // As described in the comment above, some of the inputs to the
-  // calculations we have to do are obtained concurrently and hence
-  // may be inconsistent with each other. So, this provides a
-  // defensive way of performing the subtraction and avoids the value
-  // going negative (which would mean a very large result, given that
-  // the parameter are size_t).
-  static size_t subtract_up_to_zero(size_t x, size_t y) {
-    if (x > y) {
-      return x - y;
-    } else {
-      return 0;
-    }
-  }
-
   // Recalculate all the sizes.
   void recalculate_sizes();
 
--- a/src/hotspot/share/gc/g1/g1SurvivorRegions.cpp	Mon Apr 08 21:01:17 2019 +0200
+++ b/src/hotspot/share/gc/g1/g1SurvivorRegions.cpp	Mon Apr 08 12:15:40 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -28,7 +28,9 @@
 #include "utilities/growableArray.hpp"
 #include "utilities/debug.hpp"
 
-G1SurvivorRegions::G1SurvivorRegions() : _regions(new (ResourceObj::C_HEAP, mtGC) GrowableArray<HeapRegion*>(8, true, mtGC)) {}
+G1SurvivorRegions::G1SurvivorRegions() :
+  _regions(new (ResourceObj::C_HEAP, mtGC) GrowableArray<HeapRegion*>(8, true, mtGC)),
+  _used_bytes(0) {}
 
 void G1SurvivorRegions::add(HeapRegion* hr) {
   assert(hr->is_survivor(), "should be flagged as survivor region");
@@ -51,5 +53,9 @@
 
 void G1SurvivorRegions::clear() {
   _regions->clear();
+  _used_bytes = 0;
 }
 
+void G1SurvivorRegions::add_used_bytes(size_t used_bytes) {
+  _used_bytes += used_bytes;
+}
--- a/src/hotspot/share/gc/g1/g1SurvivorRegions.hpp	Mon Apr 08 21:01:17 2019 +0200
+++ b/src/hotspot/share/gc/g1/g1SurvivorRegions.hpp	Mon Apr 08 12:15:40 2019 -0700
@@ -34,6 +34,7 @@
 class G1SurvivorRegions {
 private:
   GrowableArray<HeapRegion*>* _regions;
+  volatile size_t             _used_bytes;
 
 public:
   G1SurvivorRegions();
@@ -49,6 +50,11 @@
   const GrowableArray<HeapRegion*>* regions() const {
     return _regions;
   }
+
+  // Used bytes of all survivor regions.
+  size_t used_bytes() const { return _used_bytes; }
+
+  void add_used_bytes(size_t used_bytes);
 };
 
 #endif // SHARE_GC_G1_G1SURVIVORREGIONS_HPP
--- a/src/hotspot/share/gc/g1/vmStructs_g1.hpp	Mon Apr 08 21:01:17 2019 +0200
+++ b/src/hotspot/share/gc/g1/vmStructs_g1.hpp	Mon Apr 08 12:15:40 2019 -0700
@@ -52,8 +52,8 @@
   nonstatic_field(HeapRegionManager, _regions,          G1HeapRegionTable)    \
   nonstatic_field(HeapRegionManager, _num_committed,    uint)                 \
                                                                               \
-  nonstatic_field(G1CollectedHeap, _summary_bytes_used, size_t)               \
-  nonstatic_field(G1CollectedHeap, _hrm,                HeapRegionManager*)    \
+  volatile_nonstatic_field(G1CollectedHeap, _summary_bytes_used, size_t)      \
+  nonstatic_field(G1CollectedHeap, _hrm,                HeapRegionManager*)   \
   nonstatic_field(G1CollectedHeap, _g1mm,               G1MonitoringSupport*) \
   nonstatic_field(G1CollectedHeap, _old_set,            HeapRegionSetBase)    \
   nonstatic_field(G1CollectedHeap, _archive_set,        HeapRegionSetBase)    \
--- a/test/hotspot/jtreg/ProblemList.txt	Mon Apr 08 21:01:17 2019 +0200
+++ b/test/hotspot/jtreg/ProblemList.txt	Mon Apr 08 12:15:40 2019 -0700
@@ -67,8 +67,6 @@
 
 gc/epsilon/TestMemoryMXBeans.java 8206434 generic-all
 gc/g1/humongousObjects/objectGraphTest/TestObjectGraphAfterGC.java 8156755 generic-all
-gc/survivorAlignment/TestPromotionToSurvivor.java 8218049 generic-all
-gc/survivorAlignment/TestPromotionFromSurvivorToTenuredAfterMinorGC.java 8218049 generic-all
 gc/g1/logging/TestG1LoggingFailure.java 8169634 generic-all
 gc/g1/humongousObjects/TestHeapCounters.java 8178918 generic-all
 gc/stress/gclocker/TestGCLockerWithParallel.java 8180622 generic-all
--- a/test/hotspot/jtreg/gc/survivorAlignment/TestAllocationInEden.java	Mon Apr 08 21:01:17 2019 +0200
+++ b/test/hotspot/jtreg/gc/survivorAlignment/TestAllocationInEden.java	Mon Apr 08 12:15:40 2019 -0700
@@ -24,7 +24,7 @@
 package gc.survivorAlignment;
 
 /**
- * @test
+ * @test gc.survivorAlignment.TestAllocationInEden
  * @bug 8031323
  * @summary Verify that object's alignment in eden space is not affected by
  *          SurvivorAlignmentInBytes option.
--- a/test/hotspot/jtreg/gc/survivorAlignment/TestPromotionFromEdenToTenured.java	Mon Apr 08 21:01:17 2019 +0200
+++ b/test/hotspot/jtreg/gc/survivorAlignment/TestPromotionFromEdenToTenured.java	Mon Apr 08 12:15:40 2019 -0700
@@ -24,7 +24,7 @@
 package gc.survivorAlignment;
 
 /**
- * @test
+ * @test gc.survivorAlignment.TestPromotionFromEdenToTenured
  * @bug 8031323
  * @summary Verify that objects promoted from eden space to tenured space during
  *          full GC are not aligned to SurvivorAlignmentInBytes value.
--- a/test/hotspot/jtreg/gc/survivorAlignment/TestPromotionFromSurvivorToTenuredAfterFullGC.java	Mon Apr 08 21:01:17 2019 +0200
+++ b/test/hotspot/jtreg/gc/survivorAlignment/TestPromotionFromSurvivorToTenuredAfterFullGC.java	Mon Apr 08 12:15:40 2019 -0700
@@ -24,7 +24,7 @@
 package gc.survivorAlignment;
 
 /**
- * @test
+ * @test gc.survivorAlignment.TestPromotionFromSurvivorToTenuredAfterFullGC
  * @bug 8031323
  * @summary Verify that objects promoted from survivor space to tenured space
  *          during full GC are not aligned to SurvivorAlignmentInBytes value.
--- a/test/hotspot/jtreg/gc/survivorAlignment/TestPromotionFromSurvivorToTenuredAfterMinorGC.java	Mon Apr 08 21:01:17 2019 +0200
+++ b/test/hotspot/jtreg/gc/survivorAlignment/TestPromotionFromSurvivorToTenuredAfterMinorGC.java	Mon Apr 08 12:15:40 2019 -0700
@@ -24,13 +24,14 @@
 package gc.survivorAlignment;
 
 /**
- * @test
+ * @test gc.survivorAlignment.TestPromotionFromSurvivorToTenuredAfterMinorGC
  * @bug 8031323
  * @summary Verify that objects promoted from survivor space to tenured space
  *          when their age exceeded tenuring threshold are not aligned to
  *          SurvivorAlignmentInBytes value.
  * @requires vm.gc != "Z" & vm.gc != "Shenandoah"
  * @library /test/lib
+ * @library /
  * @modules java.base/jdk.internal.misc
  *          java.management
  * @build sun.hotspot.WhiteBox
--- a/test/hotspot/jtreg/gc/survivorAlignment/TestPromotionLABLargeSurvivorAlignment.java	Mon Apr 08 21:01:17 2019 +0200
+++ b/test/hotspot/jtreg/gc/survivorAlignment/TestPromotionLABLargeSurvivorAlignment.java	Mon Apr 08 12:15:40 2019 -0700
@@ -24,7 +24,7 @@
 package gc.survivorAlignment;
 
 /**
- * @test
+ * @test gc.survivorAlignment.TestPromotionLABLargeSurvivorAlignment
  * @bug 8060463
  * @summary Verify that objects promoted from eden space to survivor space
  *          with large values for SurvivorAlignmentInBytes succeed.
--- a/test/hotspot/jtreg/gc/survivorAlignment/TestPromotionToSurvivor.java	Mon Apr 08 21:01:17 2019 +0200
+++ b/test/hotspot/jtreg/gc/survivorAlignment/TestPromotionToSurvivor.java	Mon Apr 08 12:15:40 2019 -0700
@@ -24,12 +24,13 @@
 package gc.survivorAlignment;
 
 /**
- * @test
+ * @test gc.survivorAlignment.TestPromotionToSurvivor
  * @bug 8031323
  * @summary Verify that objects promoted from eden space to survivor space after
  *          minor GC are aligned to SurvivorAlignmentInBytes.
  * @requires vm.gc != "Z" & vm.gc != "Shenandoah"
  * @library /test/lib
+ * @library /
  * @modules java.base/jdk.internal.misc
  *          java.management
  * @build sun.hotspot.WhiteBox