Skip to content

Commit a9c9f7f

Browse files
committed
8192647: GClocker induced GCs can starve threads requiring memory leading to OOME
Reviewed-by: tschatzl, iwalulya, egahlin
1 parent aa70f0a commit a9c9f7f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+163
-935
lines changed

src/hotspot/share/gc/g1/g1CollectedHeap.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1873,7 +1873,7 @@ bool G1CollectedHeap::try_collect(GCCause::Cause cause,
18731873
return try_collect_concurrently(cause,
18741874
counters_before.total_collections(),
18751875
counters_before.old_marking_cycles_started());
1876-
} else if (cause == GCCause::_gc_locker || cause == GCCause::_wb_young_gc
1876+
} else if (cause == GCCause::_wb_young_gc
18771877
DEBUG_ONLY(|| cause == GCCause::_scavenge_alot)) {
18781878

18791879
// Schedule a standard evacuation pause. We're setting word_size

src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp

Lines changed: 7 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,7 @@ void ParallelScavengeHeap::post_initialize() {
188188
PSPromotionManager::initialize();
189189

190190
ScavengableNMethods::initialize(&_is_scavengable);
191+
GCLocker::initialize();
191192
}
192193

193194
void ParallelScavengeHeap::update_counters() {
@@ -288,7 +289,6 @@ HeapWord* ParallelScavengeHeap::mem_allocate_work(size_t size,
288289

289290
uint loop_count = 0;
290291
uint gc_count = 0;
291-
uint gclocker_stalled_count = 0;
292292

293293
while (result == nullptr) {
294294
// We don't want to have multiple collections for a single filled generation.
@@ -318,37 +318,10 @@ HeapWord* ParallelScavengeHeap::mem_allocate_work(size_t size,
318318
return result;
319319
}
320320
}
321-
322-
if (gclocker_stalled_count > GCLockerRetryAllocationCount) {
323-
return nullptr;
324-
}
325-
326-
// Failed to allocate without a gc.
327-
if (GCLocker::is_active_and_needs_gc()) {
328-
// If this thread is not in a jni critical section, we stall
329-
// the requestor until the critical section has cleared and
330-
// GC allowed. When the critical section clears, a GC is
331-
// initiated by the last thread exiting the critical section; so
332-
// we retry the allocation sequence from the beginning of the loop,
333-
// rather than causing more, now probably unnecessary, GC attempts.
334-
JavaThread* jthr = JavaThread::current();
335-
if (!jthr->in_critical()) {
336-
MutexUnlocker mul(Heap_lock);
337-
GCLocker::stall_until_clear();
338-
gclocker_stalled_count += 1;
339-
continue;
340-
} else {
341-
if (CheckJNICalls) {
342-
fatal("Possible deadlock due to allocating while"
343-
" in jni critical section");
344-
}
345-
return nullptr;
346-
}
347-
}
348321
}
349322

350-
if (result == nullptr) {
351-
// Generate a VM operation
323+
assert(result == nullptr, "inv");
324+
{
352325
VM_ParallelCollectForAllocation op(size, is_tlab, gc_count);
353326
VMThread::execute(&op);
354327

@@ -358,13 +331,6 @@ HeapWord* ParallelScavengeHeap::mem_allocate_work(size_t size,
358331
if (op.prologue_succeeded()) {
359332
assert(is_in_or_null(op.result()), "result not in heap");
360333

361-
// If GC was locked out during VM operation then retry allocation
362-
// and/or stall as necessary.
363-
if (op.gc_locked()) {
364-
assert(op.result() == nullptr, "must be null if gc_locked() is true");
365-
continue; // retry and/or stall as necessary
366-
}
367-
368334
// Exit the loop if the gc time limit has been exceeded.
369335
// The allocation must have failed above ("result" guarding
370336
// this path is null) and the most recent collection has exceeded the
@@ -416,18 +382,15 @@ HeapWord* ParallelScavengeHeap::allocate_old_gen_and_record(size_t size) {
416382
}
417383

418384
HeapWord* ParallelScavengeHeap::mem_allocate_old_gen(size_t size) {
419-
if (!should_alloc_in_eden(size) || GCLocker::is_active_and_needs_gc()) {
420-
// Size is too big for eden, or gc is locked out.
385+
if (!should_alloc_in_eden(size)) {
386+
// Size is too big for eden.
421387
return allocate_old_gen_and_record(size);
422388
}
423389

424390
return nullptr;
425391
}
426392

427393
void ParallelScavengeHeap::do_full_collection(bool clear_all_soft_refs) {
428-
if (GCLocker::check_active_before_gc()) {
429-
return;
430-
}
431394
PSParallelCompact::invoke(clear_all_soft_refs);
432395
}
433396

@@ -446,11 +409,6 @@ HeapWord* ParallelScavengeHeap::satisfy_failed_allocation(size_t size, bool is_t
446409

447410
HeapWord* result = nullptr;
448411

449-
GCLocker::check_active_before_gc();
450-
if (GCLocker::is_active_and_needs_gc()) {
451-
return expand_heap_and_allocate(size, is_tlab);
452-
}
453-
454412
// If young-gen can handle this allocation, attempt young-gc firstly.
455413
bool should_run_young_gc = is_tlab || should_alloc_in_eden(size);
456414
collect_at_safepoint(!should_run_young_gc);
@@ -544,10 +502,6 @@ void ParallelScavengeHeap::collect(GCCause::Cause cause) {
544502
full_gc_count = total_full_collections();
545503
}
546504

547-
if (GCLocker::should_discard(cause, gc_count)) {
548-
return;
549-
}
550-
551505
while (true) {
552506
VM_ParallelGCCollect op(gc_count, full_gc_count, cause);
553507
VMThread::execute(&op);
@@ -562,20 +516,7 @@ void ParallelScavengeHeap::collect(GCCause::Cause cause) {
562516
return;
563517
}
564518
}
565-
566-
if (GCLocker::is_active_and_needs_gc()) {
567-
// If GCLocker is active, wait until clear before retrying.
568-
GCLocker::stall_until_clear();
569-
}
570-
}
571-
}
572-
573-
void ParallelScavengeHeap::try_collect_at_safepoint(bool full) {
574-
assert(SafepointSynchronize::is_at_safepoint(), "precondition");
575-
if (GCLocker::check_active_before_gc()) {
576-
return;
577519
}
578-
collect_at_safepoint(full);
579520
}
580521

581522
bool ParallelScavengeHeap::must_clear_all_soft_refs() {
@@ -889,11 +830,11 @@ GrowableArray<MemoryPool*> ParallelScavengeHeap::memory_pools() {
889830
}
890831

891832
void ParallelScavengeHeap::pin_object(JavaThread* thread, oop obj) {
892-
GCLocker::lock_critical(thread);
833+
GCLocker::enter(thread);
893834
}
894835

895836
void ParallelScavengeHeap::unpin_object(JavaThread* thread, oop obj) {
896-
GCLocker::unlock_critical(thread);
837+
GCLocker::exit(thread);
897838
}
898839

899840
void ParallelScavengeHeap::update_parallel_worker_threads_cpu_time() {

src/hotspot/share/gc/parallel/parallelScavengeHeap.hpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,6 @@ class ParallelScavengeHeap : public CollectedHeap {
9595

9696
void update_parallel_worker_threads_cpu_time();
9797

98-
void collect_at_safepoint(bool full);
99-
10098
bool must_clear_all_soft_refs();
10199

102100
HeapWord* allocate_new_tlab(size_t min_size, size_t requested_size, size_t* actual_size) override;
@@ -198,7 +196,7 @@ class ParallelScavengeHeap : public CollectedHeap {
198196
// Support for System.gc()
199197
void collect(GCCause::Cause cause) override;
200198

201-
void try_collect_at_safepoint(bool full);
199+
void collect_at_safepoint(bool full);
202200

203201
void ensure_parsability(bool retire_tlabs) override;
204202
void resize_all_tlabs() override;

src/hotspot/share/gc/parallel/psOldGen.cpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -217,9 +217,6 @@ bool PSOldGen::expand(size_t bytes) {
217217
success = expand_to_reserved();
218218
}
219219

220-
if (success && GCLocker::is_active_and_needs_gc()) {
221-
log_debug(gc)("Garbage collection disabled, expanded heap instead");
222-
}
223220
return success;
224221
}
225222

src/hotspot/share/gc/parallel/psParallelCompact.cpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -993,10 +993,6 @@ bool PSParallelCompact::invoke_no_policy(bool clear_all_soft_refs) {
993993
assert(SafepointSynchronize::is_at_safepoint(), "must be at a safepoint");
994994
assert(ref_processor() != nullptr, "Sanity");
995995

996-
if (GCLocker::check_active_before_gc()) {
997-
return false;
998-
}
999-
1000996
ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
1001997

1002998
GCIdMark gc_id_mark;

src/hotspot/share/gc/parallel/psVMOperations.cpp

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,14 +43,10 @@ void VM_ParallelCollectForAllocation::doit() {
4343

4444
GCCauseSetter gccs(heap, _gc_cause);
4545
_result = heap->satisfy_failed_allocation(_word_size, _is_tlab);
46-
47-
if (_result == nullptr && GCLocker::is_active_and_needs_gc()) {
48-
set_gc_locked();
49-
}
5046
}
5147

5248
static bool is_cause_full(GCCause::Cause cause) {
53-
return (cause != GCCause::_gc_locker) && (cause != GCCause::_wb_young_gc)
49+
return (cause != GCCause::_wb_young_gc)
5450
DEBUG_ONLY(&& (cause != GCCause::_scavenge_alot));
5551
}
5652

@@ -64,5 +60,5 @@ void VM_ParallelGCCollect::doit() {
6460
ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
6561

6662
GCCauseSetter gccs(heap, _gc_cause);
67-
heap->try_collect_at_safepoint(_full);
63+
heap->collect_at_safepoint(_full);
6864
}

src/hotspot/share/gc/serial/defNewGeneration.cpp

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -367,18 +367,6 @@ bool DefNewGeneration::expand(size_t bytes) {
367367
SpaceMangler::mangle_region(mangle_region);
368368
}
369369

370-
// Do not attempt an expand-to-the reserve size. The
371-
// request should properly observe the maximum size of
372-
// the generation so an expand-to-reserve should be
373-
// unnecessary. Also a second call to expand-to-reserve
374-
// value potentially can cause an undue expansion.
375-
// For example if the first expand fail for unknown reasons,
376-
// but the second succeeds and expands the heap to its maximum
377-
// value.
378-
if (GCLocker::is_active()) {
379-
log_debug(gc)("Garbage collection disabled, expanded heap instead");
380-
}
381-
382370
return success;
383371
}
384372

0 commit comments

Comments
 (0)