Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

8268122: Add specific gc cause for G1 full collections #4357

Closed
wants to merge 5 commits into from
Closed
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
@@ -1095,6 +1095,18 @@ void G1CollectedHeap::do_full_collection(bool clear_all_soft_refs) {
do_maximum_compaction);
}

bool G1CollectedHeap::upgrade_to_full_collection() {
GCCauseSetter compaction(this, GCCause::_g1_compaction_pause);
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();

@@ -1112,7 +1124,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;
@@ -1134,13 +1146,18 @@ 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;
GCCauseSetter compaction(this, GCCause::_g1_compaction_pause);
// 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;
@@ -1154,7 +1171,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);

@@ -1165,7 +1182,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);

@@ -1176,7 +1193,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);

@@ -2834,15 +2851,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;
}

@@ -516,6 +516,9 @@ class G1CollectedHeap : public CollectedHeap {
// 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 @@ class G1CollectedHeap : public CollectedHeap {
// 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);

@@ -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;
}
}

@@ -138,10 +140,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();
}
}
}

@@ -99,6 +99,9 @@ const char* GCCause::to_string(GCCause::Cause cause) {
case _g1_periodic_collection:
return "G1 Periodic Collection";

case _g1_compaction_pause:
return "G1 Compaction Pause";

case _dcmd_gc_run:
return "Diagnostic Command";

@@ -73,6 +73,7 @@ class GCCause : public AllStatic {
_g1_inc_collection_pause,
_g1_humongous_allocation,
_g1_periodic_collection,
_g1_compaction_pause,

_dcmd_gc_run,

@@ -40,7 +40,7 @@ public static void main(String[] args) throws Exception {
String testID = "G1ConcurrentMark";
String[] vmFlags = {"-XX:+UseG1GC", "-XX:+ExplicitGCInvokesConcurrent"};
String[] gcNames = {GCHelper.gcG1New, GCHelper.gcG1Old, GCHelper.gcG1Full};
String[] gcCauses = {"G1 Evacuation Pause", "Allocation Failure", "System.gc()"};
String[] gcCauses = {"G1 Evacuation Pause", "G1 Compaction Pause", "System.gc()"};
GCGarbageCollectionUtil.test(testID, vmFlags, gcNames, gcCauses);
}
}
@@ -40,7 +40,7 @@ public static void main(String[] args) throws Exception {
String testID = "G1FullCollection";
String[] vmFlags = {"-XX:+UseG1GC"};
String[] gcNames = {GCHelper.gcG1New, GCHelper.gcG1Old, GCHelper.gcG1Full};
String[] gcCauses = {"G1 Evacuation Pause", "Allocation Failure", "System.gc()"};
String[] gcCauses = {"G1 Evacuation Pause", "G1 Compaction Pause", "System.gc()"};
GCGarbageCollectionUtil.test(testID, vmFlags, gcNames, gcCauses);
}
}