8218049: Survivor MemoryMXBean used() size granularity is region based
Reviewed-by: tschatzl, kbarrett
--- 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