Skip to content

Commit

Permalink
8314935: Shenandoah: Unable to throw OOME on back-to-back Full GCs
Browse files Browse the repository at this point in the history
Backport-of: 716201c77d160dc78db61957aa002eef71641688
  • Loading branch information
William Kemper authored and Paul Hohensee committed Sep 12, 2023
1 parent 1dac78c commit 9b983f3
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ class ShenandoahCollectorPolicy : public CHeapObj<mtGC> {
private:
size_t _success_concurrent_gcs;
size_t _success_degenerated_gcs;
size_t _success_full_gcs;
// Written by control thread, read by mutators
volatile size_t _success_full_gcs;
size_t _alloc_failure_degenerated;
size_t _alloc_failure_degenerated_upgrade_to_full;
size_t _alloc_failure_full;
Expand Down Expand Up @@ -82,6 +83,10 @@ class ShenandoahCollectorPolicy : public CHeapObj<mtGC> {
size_t cycle_counter() const;

void print_gc_stats(outputStream* out) const;

size_t full_gc_count() const {
return _success_full_gcs + _alloc_failure_degenerated_upgrade_to_full;
}
};

#endif // SHARE_GC_SHENANDOAH_SHENANDOAHCOLLECTORPOLICY_HPP
21 changes: 5 additions & 16 deletions src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -838,25 +838,14 @@ HeapWord* ShenandoahHeap::allocate_memory(ShenandoahAllocRequest& req) {
// It might happen that one of the threads requesting allocation would unblock
// way later after GC happened, only to fail the second allocation, because
// other threads have already depleted the free storage. In this case, a better
// strategy is to try again, as long as GC makes progress.
//
// Then, we need to make sure the allocation was retried after at least one
// Full GC, which means we want to try more than ShenandoahFullGCThreshold times.

size_t tries = 0;

while (result == nullptr && _progress_last_gc.is_set()) {
tries++;
control_thread()->handle_alloc_failure(req);
result = allocate_memory_under_lock(req, in_new_region);
}

while (result == nullptr && tries <= ShenandoahFullGCThreshold) {
tries++;
// strategy is to try again, as long as GC makes progress (or until at least
// one full GC has completed).
size_t original_count = shenandoah_policy()->full_gc_count();
while (result == nullptr
&& (_progress_last_gc.is_set() || original_count == shenandoah_policy()->full_gc_count())) {
control_thread()->handle_alloc_failure(req);
result = allocate_memory_under_lock(req, in_new_region);
}

} else {
assert(req.is_gc_alloc(), "Can only accept GC allocs here");
result = allocate_memory_under_lock(req, in_new_region);
Expand Down

1 comment on commit 9b983f3

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

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

Please sign in to comment.