Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
18ab073
Some cleanup and a test harness for adaptive tenuring
earthling-amzn Aug 1, 2025
280d8d1
Assert current behavior is expected
earthling-amzn Aug 11, 2025
47a84e0
Make evac tracking a runtime feature, add logging for plab management
earthling-amzn Aug 12, 2025
43d25e3
Instrumentation tweaks
earthling-amzn Aug 13, 2025
c3b4e89
Instrumentation tweaks
earthling-amzn Aug 13, 2025
be111f0
Are some threads not getting plab promotions re-enabled?
earthling-amzn Aug 13, 2025
0429530
Re-enable plab promotions for all threads when plabs are retired
earthling-amzn Aug 14, 2025
7dd61a3
Remove unused ShenandoahThreadLocalData::_paced_time
earthling-amzn Aug 14, 2025
101cdf2
Log percentage of population which is above tenuring threshold
earthling-amzn Aug 14, 2025
c6a3467
Tone down some log messages, draw the tenuring threshold line above t…
earthling-amzn Aug 14, 2025
038aa46
Remove census-at-evac option
earthling-amzn Aug 15, 2025
090ae87
Little clean up as I read
earthling-amzn Aug 15, 2025
071bc88
Deduplicate some collection set logging
earthling-amzn Aug 15, 2025
7c2de24
Idle clean ups, logging improvements
earthling-amzn Aug 18, 2025
f472787
Merge remote-tracking branch 'jdk/master' into adaptive-tenuring-thre…
earthling-amzn Aug 18, 2025
8d7cd39
Update unit test, fix slowdebug build issue
earthling-amzn Aug 19, 2025
b13e8b1
Remove outdated comment
earthling-amzn Aug 19, 2025
86c429a
Add more census updates, exhibit current behavior in test
earthling-amzn Aug 19, 2025
704753f
Idle clean ups
earthling-amzn Aug 19, 2025
48a330f
Merge branch 'adaptive-tenuring-threshold' into make-evac-tracking-ru…
earthling-amzn Aug 19, 2025
a3e5fb4
Add a method to get the total bytes occupied by objects eligible for …
earthling-amzn Aug 19, 2025
c4fb8cf
Instrumentation to guage potential changes to promotion reserves
earthling-amzn Aug 19, 2025
ca6ca98
Fix linker error
earthling-amzn Aug 20, 2025
89a6212
How is promotion potential higher than next cycle's tenurable objects…
earthling-amzn Aug 20, 2025
d3a63ec
Oops, age table sizes are words
earthling-amzn Aug 20, 2025
32f6b3b
Add test that simulates promotion above tenuring age
earthling-amzn Aug 20, 2025
642c1a0
Checkpoint, tests pass
earthling-amzn Aug 21, 2025
82c06f2
Clean up tests
earthling-amzn Aug 22, 2025
2c7275f
Merge tag 'jdk-26+12' into adaptive-tenuring-threshold
earthling-amzn Aug 22, 2025
64c6839
Revert unintended change
earthling-amzn Aug 22, 2025
830f2c6
Merge remote-tracking branch 'origin/adaptive-tenuring-threshold' int…
earthling-amzn Aug 22, 2025
b3109ed
Use age census to inform size of old generation
earthling-amzn Aug 22, 2025
8b2fb41
Fix release build
earthling-amzn Aug 22, 2025
225c6ed
Fix age table printing (again)
earthling-amzn Aug 22, 2025
c663e2f
Track and print promotion failure stats
earthling-amzn Aug 22, 2025
fb5e0fc
Use age census to size promotion reserve for current cycle
earthling-amzn Aug 22, 2025
e1cdba7
Adjust promotion reserve based only on old regions that have been add…
earthling-amzn Aug 22, 2025
d306a51
Why do we keep giving away all our old reserve?
earthling-amzn Aug 22, 2025
25c488e
Count promotion reserve in old consumed
earthling-amzn Aug 23, 2025
b9e16d2
Fix windows build
earthling-amzn Aug 25, 2025
268bddf
Keep promotion reserve (we already accounted for this when transferri…
earthling-amzn Aug 25, 2025
2bd2e41
More instrumentation
earthling-amzn Aug 25, 2025
9f2be25
Merge remote-tracking branch 'earthling-jdk/adaptive-tenuring-thresho…
earthling-amzn Aug 25, 2025
5845982
Merge remote-tracking branch 'jdk/master' into make-evac-tracking-run…
earthling-amzn Sep 10, 2025
3037ca8
Tweak comment
earthling-amzn Sep 11, 2025
dc3458a
Merge remote-tracking branch 'jdk/master' into promotion-budget-impro…
earthling-amzn Sep 25, 2025
3841fc0
Merge remote-tracking branch 'jdk/master' into promotion-budget-impro…
earthling-amzn Sep 25, 2025
38cda58
Merge fallout
earthling-amzn Sep 25, 2025
5809aa5
More accurate method names for cset fields, consider promotion reserv…
earthling-amzn Oct 1, 2025
35e0417
Only use old generation in generational mode
earthling-amzn Oct 1, 2025
1f757d1
Fix wrong asserts
earthling-amzn Oct 1, 2025
fd9619d
Little cleanup
earthling-amzn Oct 2, 2025
8fca0b6
Fix windows build
earthling-amzn Oct 6, 2025
09926eb
Fix windows build more
earthling-amzn Oct 6, 2025
b4d1cf9
Review feedback, bug fixes
earthling-amzn Oct 7, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ bool ShenandoahOldHeuristics::prime_collection_set(ShenandoahCollectionSet* coll
// If region r is evacuated to fragmented memory (to free memory within a partially used region), then we need
// to decrease the capacity of the fragmented memory by the scaled loss.

size_t live_data_for_evacuation = r->get_live_data_bytes();
const size_t live_data_for_evacuation = r->get_live_data_bytes();
size_t lost_available = r->free();

if ((lost_available > 0) && (excess_fragmented_available > 0)) {
Expand Down Expand Up @@ -169,7 +169,9 @@ bool ShenandoahOldHeuristics::prime_collection_set(ShenandoahCollectionSet* coll
// We were not able to account for the lost free memory within fragmented memory, so we need to take this
// allocation out of unfragmented memory. Unfragmented memory does not need to account for loss of free.
if (live_data_for_evacuation > unfragmented_available) {
// There is not room to evacuate this region or any that come after it in within the candidates array.
// There is no room to evacuate this region or any that come after it in within the candidates array.
log_debug(gc, cset)("Not enough unfragmented memory (%zu) to hold evacuees (%zu) from region: (%zu)",
unfragmented_available, live_data_for_evacuation, r->index());
break;
} else {
unfragmented_available -= live_data_for_evacuation;
Expand All @@ -187,7 +189,9 @@ bool ShenandoahOldHeuristics::prime_collection_set(ShenandoahCollectionSet* coll
evacuation_need = 0;
}
if (evacuation_need > unfragmented_available) {
// There is not room to evacuate this region or any that come after it in within the candidates array.
// There is no room to evacuate this region or any that come after it in within the candidates array.
log_debug(gc, cset)("Not enough unfragmented memory (%zu) to hold evacuees (%zu) from region: (%zu)",
unfragmented_available, live_data_for_evacuation, r->index());
break;
} else {
unfragmented_available -= evacuation_need;
Expand Down
13 changes: 13 additions & 0 deletions src/hotspot/share/gc/shenandoah/shenandoahAgeCensus.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,19 @@ void ShenandoahAgeCensus::update_census(size_t age0_pop) {
}


size_t ShenandoahAgeCensus::get_tenurable_bytes(const uint tenuring_threshold) const {
assert(_epoch < MAX_SNAPSHOTS, "Out of bounds");
size_t total = 0;
const AgeTable* pv = _global_age_tables[_epoch];
for (uint i = 0; i < MAX_COHORTS; i++) {
if (i >= tenuring_threshold) {
total += pv->sizes[i];
}
}
return total * HeapWordSize;
}


// Reset the epoch for the global age tables,
// clearing all history.
void ShenandoahAgeCensus::reset_global() {
Expand Down
6 changes: 6 additions & 0 deletions src/hotspot/share/gc/shenandoah/shenandoahAgeCensus.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,12 @@ class ShenandoahAgeCensus: public CHeapObj<mtGC> {
// allocated when the concurrent marking was in progress.
void update_census(size_t age0_pop);

// Return the total size of the population above the given threshold for the current epoch
size_t get_tenurable_bytes(uint tenuring_threshold) const;

// As above, but use the current tenuring threshold by default
size_t get_tenurable_bytes() const { return get_tenurable_bytes(tenuring_threshold()); }

// Reset the epoch, clearing accumulated census history
// Note: this isn't currently used, but reserved for planned
// future usage.
Expand Down
6 changes: 3 additions & 3 deletions src/hotspot/share/gc/shenandoah/shenandoahCollectionSet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -225,9 +225,9 @@ void ShenandoahCollectionSet::summarize(size_t total_garbage, size_t immediate_g
count());

if (garbage() > 0) {
const size_t young_evac_bytes = get_young_bytes_reserved_for_evacuation();
const size_t promote_evac_bytes = get_young_bytes_to_be_promoted();
const size_t old_evac_bytes = get_old_bytes_reserved_for_evacuation();
const size_t young_evac_bytes = get_live_bytes_in_untenurable_regions();
const size_t promote_evac_bytes = get_live_bytes_in_tenurable_regions();
const size_t old_evac_bytes = get_live_bytes_in_old_regions();
const size_t total_evac_bytes = young_evac_bytes + promote_evac_bytes + old_evac_bytes;
ls.print_cr("Evacuation Targets: "
"YOUNG: " PROPERFMT ", " "PROMOTE: " PROPERFMT ", " "OLD: " PROPERFMT ", " "TOTAL: " PROPERFMT,
Expand Down
10 changes: 5 additions & 5 deletions src/hotspot/share/gc/shenandoah/shenandoahCollectionSet.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,14 +109,14 @@ class ShenandoahCollectionSet : public CHeapObj<mtGC> {
// Prints a summary of the collection set when gc+ergo=info
void summarize(size_t total_garbage, size_t immediate_garbage, size_t immediate_regions) const;

// Returns the amount of live bytes in young regions in the collection set. It is not known how many of these bytes will be promoted.
inline size_t get_young_bytes_reserved_for_evacuation() const;
// Returns the amount of live bytes in young regions with an age below the tenuring threshold.
inline size_t get_live_bytes_in_untenurable_regions() const;

// Returns the amount of live bytes in old regions in the collection set.
inline size_t get_old_bytes_reserved_for_evacuation() const;
inline size_t get_live_bytes_in_old_regions() const;

// Returns the amount of live bytes in young regions with an age above the tenuring threshold.
inline size_t get_young_bytes_to_be_promoted() const;
inline size_t get_live_bytes_in_tenurable_regions() const;

// Returns the amount of free bytes in young regions in the collection set.
size_t get_young_available_bytes_collected() const { return _young_available_bytes_collected; }
Expand All @@ -125,7 +125,7 @@ class ShenandoahCollectionSet : public CHeapObj<mtGC> {
inline size_t get_old_garbage() const;

bool is_preselected(size_t region_idx) {
assert(_preselected_regions != nullptr, "Missing etsablish after abandon");
assert(_preselected_regions != nullptr, "Missing establish after abandon");
return _preselected_regions[region_idx];
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,15 +54,15 @@ bool ShenandoahCollectionSet::is_in_loc(void* p) const {
return _biased_cset_map[index] == 1;
}

size_t ShenandoahCollectionSet::get_old_bytes_reserved_for_evacuation() const {
size_t ShenandoahCollectionSet::get_live_bytes_in_old_regions() const {
return _old_bytes_to_evacuate;
}

size_t ShenandoahCollectionSet::get_young_bytes_reserved_for_evacuation() const {
size_t ShenandoahCollectionSet::get_live_bytes_in_untenurable_regions() const {
return _young_bytes_to_evacuate - _young_bytes_to_promote;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm wondering if these new names properly reflect the intention. It seems get_live_byte_in_young_regions() really means get_live_bytes_that_we_intend_to_evacuate_to_young(). (This number does not include _live_bytes_in_young_regions() that we expect to evacuate to old.)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I called the complementary method get_live_bytes_in_tenurable_regions. How about get_live_bytes_in_untenurable_regions?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm still maybe a bit confused. Is it get_untenurable_live_bytes_in_young_regions()? Are we distinguishing?

So we have a total of N live bytes within young regions that have been placed into the collection set. We expect that P bytes (P < N) will be promoted, and the remaining S bytes (S + P == N) will be evacuated to "survivor space" within young.

Does get_live_bytes_in_untenurable_regions() equal P + S?

}

size_t ShenandoahCollectionSet::get_young_bytes_to_be_promoted() const {
size_t ShenandoahCollectionSet::get_live_bytes_in_tenurable_regions() const {
return _young_bytes_to_promote;
}

Expand Down
Loading