8268163: Change the order of fallback full GCs in G1

Reviewed-by: kbarrett, tschatzl
This commit is contained in:
Stefan Johansson 2021-06-09 13:43:48 +00:00
parent 7b1e4024c0
commit 5fbb62c741
3 changed files with 44 additions and 26 deletions

View File

@ -1138,6 +1138,17 @@ void G1CollectedHeap::do_full_collection(bool clear_all_soft_refs) {
do_maximum_compaction);
}
bool G1CollectedHeap::upgrade_to_full_collection() {
log_info(gc, ergo)("Attempting full compaction clearing soft references");
bool success = do_full_collection(false /* explicit gc */,
true /* clear_all_soft_refs */,
false /* do_maximum_compaction */);
// do_full_collection only fails if blocked by GC locker and that can't
// be the case here since we only call this when already completed one gc.
assert(success, "invariant");
return success;
}
void G1CollectedHeap::resize_heap_if_necessary() {
assert_at_safepoint_on_vm_thread();
@ -1155,7 +1166,7 @@ void G1CollectedHeap::resize_heap_if_necessary() {
HeapWord* G1CollectedHeap::satisfy_failed_allocation_helper(size_t word_size,
bool do_gc,
bool clear_all_soft_refs,
bool maximum_compaction,
bool expect_null_mutator_alloc_region,
bool* gc_succeeded) {
*gc_succeeded = true;
@ -1177,13 +1188,17 @@ HeapWord* G1CollectedHeap::satisfy_failed_allocation_helper(size_t word_size,
}
if (do_gc) {
// When clear_all_soft_refs is set we want to do a maximum compaction
// not leaving any dead wood.
bool do_maximum_compaction = clear_all_soft_refs;
// Expansion didn't work, we'll try to do a Full GC.
// If maximum_compaction is set we clear all soft references and don't
// allow any dead wood to be left on the heap.
if (maximum_compaction) {
log_info(gc, ergo)("Attempting maximum full compaction clearing soft references");
} else {
log_info(gc, ergo)("Attempting full compaction");
}
*gc_succeeded = do_full_collection(false, /* explicit_gc */
clear_all_soft_refs,
do_maximum_compaction);
maximum_compaction /* clear_all_soft_refs */ ,
maximum_compaction /* do_maximum_compaction */);
}
return NULL;
@ -1197,7 +1212,7 @@ HeapWord* G1CollectedHeap::satisfy_failed_allocation(size_t word_size,
HeapWord* result =
satisfy_failed_allocation_helper(word_size,
true, /* do_gc */
false, /* clear_all_soft_refs */
false, /* maximum_collection */
false, /* expect_null_mutator_alloc_region */
succeeded);
@ -1208,7 +1223,7 @@ HeapWord* G1CollectedHeap::satisfy_failed_allocation(size_t word_size,
// Attempts to allocate followed by Full GC that will collect all soft references.
result = satisfy_failed_allocation_helper(word_size,
true, /* do_gc */
true, /* clear_all_soft_refs */
true, /* maximum_collection */
true, /* expect_null_mutator_alloc_region */
succeeded);
@ -1219,7 +1234,7 @@ HeapWord* G1CollectedHeap::satisfy_failed_allocation(size_t word_size,
// Attempts to allocate, no GC
result = satisfy_failed_allocation_helper(word_size,
false, /* do_gc */
false, /* clear_all_soft_refs */
false, /* maximum_collection */
true, /* expect_null_mutator_alloc_region */
succeeded);
@ -2875,15 +2890,6 @@ bool G1CollectedHeap::do_collection_pause_at_safepoint(double target_pause_time_
}
do_collection_pause_at_safepoint_helper(target_pause_time_ms);
if (should_upgrade_to_full_gc(gc_cause())) {
log_info(gc, ergo)("Attempting maximally compacting collection");
bool result = do_full_collection(false /* explicit gc */,
true /* clear_all_soft_refs */,
false /* do_maximum_compaction */);
// do_full_collection only fails if blocked by GC locker, but
// we've already checked for that above.
assert(result, "invariant");
}
return true;
}

View File

@ -516,6 +516,9 @@ private:
// Callback from VM_G1CollectFull operation, or collect_as_vm_thread.
virtual void do_full_collection(bool clear_all_soft_refs);
// Helper to do a full collection that clears soft references.
bool upgrade_to_full_collection();
// Callback from VM_G1CollectForAllocation operation.
// This function does everything necessary/possible to satisfy a
// failed allocation request (including collection, expansion, etc.)
@ -534,7 +537,7 @@ private:
// Helper method for satisfy_failed_allocation()
HeapWord* satisfy_failed_allocation_helper(size_t word_size,
bool do_gc,
bool clear_all_soft_refs,
bool maximum_compaction,
bool expect_null_mutator_alloc_region,
bool* gc_succeeded);

View File

@ -94,14 +94,16 @@ void VM_G1TryInitiateConcMark::doit() {
// request will be remembered for a later partial collection, even though
// we've rejected this request.
_whitebox_attached = true;
} else if (g1h->do_collection_pause_at_safepoint(_target_pause_time_ms)) {
_gc_succeeded = true;
} else {
} else if (!g1h->do_collection_pause_at_safepoint(_target_pause_time_ms)) {
// Failure to perform the collection at all occurs because GCLocker is
// active, and we have the bad luck to be the collection request that
// makes a later _gc_locker collection needed. (Else we would have hit
// the GCLocker check in the prologue.)
_transient_failure = true;
} else if (g1h->should_upgrade_to_full_gc(_gc_cause)) {
_gc_succeeded = g1h->upgrade_to_full_collection();
} else {
_gc_succeeded = true;
}
}
@ -143,10 +145,17 @@ void VM_G1CollectForAllocation::doit() {
// Try a partial collection of some kind.
_gc_succeeded = g1h->do_collection_pause_at_safepoint(_target_pause_time_ms);
if (_gc_succeeded && (_word_size > 0)) {
// An allocation had been requested. Do it, eventually trying a stronger
// kind of GC.
_result = g1h->satisfy_failed_allocation(_word_size, &_gc_succeeded);
if (_gc_succeeded) {
if (_word_size > 0) {
// An allocation had been requested. Do it, eventually trying a stronger
// kind of GC.
_result = g1h->satisfy_failed_allocation(_word_size, &_gc_succeeded);
} else if (g1h->should_upgrade_to_full_gc(_gc_cause)) {
// There has been a request to perform a GC to free some space. We have no
// information on how much memory has been asked for. In case there are
// absolutely no regions left to allocate into, do a full compaction.
_gc_succeeded = g1h->upgrade_to_full_collection();
}
}
}