# HG changeset patch # User johnc # Date 1338311882 25200 # Node ID b2bee9c4b41d144111a1d5745e7a36d08bfebbee # Parent 57370da2f61d99d85eb8dc49afbe1858fa90760e 7143858: G1: Back to back young GCs with the second GC having a minimally sized eden Summary: Before the last thread to leave a JNI critical region was able to schedule a GCLocker Initiated GC, another thread was attempting an allocation and saw that the GCLocker region was no longer active and successfully scheduled a GC. Stall allocating threads until the GCLocker Initiated GC is performed and then retry the allocation. Reviewed-by: brutisso, huntch diff -r 57370da2f61d -r b2bee9c4b41d hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Mon May 21 14:59:59 2012 +0200 +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Tue May 29 10:18:02 2012 -0700 @@ -952,9 +952,18 @@ } should_try_gc = false; } else { - // Read the GC count while still holding the Heap_lock. - gc_count_before = total_collections(); - should_try_gc = true; + // The GCLocker may not be active but the GCLocker initiated + // GC may not yet have been performed (GCLocker::needs_gc() + // returns true). In this case we do not try this GC and + // wait until the GCLocker initiated GC is performed, and + // then retry the allocation. + if (GC_locker::needs_gc()) { + should_try_gc = false; + } else { + // Read the GC count while still holding the Heap_lock. + gc_count_before = total_collections(); + should_try_gc = true; + } } } @@ -975,6 +984,9 @@ return NULL; } } else { + // The GCLocker is either active or the GCLocker initiated + // GC has not yet been performed. Stall until it is and + // then retry the allocation. GC_locker::stall_until_clear(); } @@ -1054,9 +1066,18 @@ if (GC_locker::is_active_and_needs_gc()) { should_try_gc = false; } else { - // Read the GC count while still holding the Heap_lock. - gc_count_before = total_collections(); - should_try_gc = true; + // The GCLocker may not be active but the GCLocker initiated + // GC may not yet have been performed (GCLocker::needs_gc() + // returns true). In this case we do not try this GC and + // wait until the GCLocker initiated GC is performed, and + // then retry the allocation. + if (GC_locker::needs_gc()) { + should_try_gc = false; + } else { + // Read the GC count while still holding the Heap_lock. + gc_count_before = total_collections(); + should_try_gc = true; + } } } @@ -1081,6 +1102,9 @@ return NULL; } } else { + // The GCLocker is either active or the GCLocker initiated + // GC has not yet been performed. Stall until it is and + // then retry the allocation. GC_locker::stall_until_clear(); }