Skip to content

Commit d3b9b36

Browse files
committed
8308009: Generational ZGC: OOM before clearing all SoftReferences
Reviewed-by: stefank, aboldtch
1 parent bac02b6 commit d3b9b36

File tree

6 files changed

+26
-16
lines changed

6 files changed

+26
-16
lines changed

src/hotspot/share/gc/z/zDriver.cpp

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,14 @@ static bool should_preclean_young(GCCause::Cause cause) {
302302
return true;
303303
}
304304

305+
// It is important that when soft references are cleared, we also pre-clean the young
306+
// generation, as we might otherwise throw premature OOM. Therefore, all causes that
307+
// trigger soft ref cleaning must also trigger pre-cleaning of young gen. If allocations
308+
// stalled when checking for soft ref cleaning, then since we hold the driver locker all
309+
// the way until we check for young gen pre-cleaning, we can be certain that we should
310+
// catch that above and perform young gen pre-cleaning.
311+
assert(!should_clear_soft_references(cause), "Clearing soft references without pre-cleaning young gen");
312+
305313
// Preclean young if implied by configuration
306314
return ScavengeBeforeFullGC;
307315
}
@@ -385,10 +393,6 @@ class ZDriverScopeMajor : public StackObj {
385393
_gc_cause_setter(ZDriver::major(), _gc_cause),
386394
_stat_timer(ZPhaseCollectionMajor, gc_timer),
387395
_tracer(false /* minor */) {
388-
// Set up soft reference policy
389-
const bool clear = should_clear_soft_references(request.cause());
390-
ZGeneration::old()->set_soft_reference_policy(clear);
391-
392396
// Select number of worker threads to use
393397
ZGeneration::young()->set_active_workers(request.young_nworkers());
394398
ZGeneration::old()->set_active_workers(request.old_nworkers());
@@ -441,12 +445,12 @@ void ZDriverMajor::gc(const ZDriverRequest& request) {
441445
collect_old();
442446
}
443447

444-
static void handle_alloc_stalling_for_old() {
445-
ZHeap::heap()->handle_alloc_stalling_for_old();
448+
static void handle_alloc_stalling_for_old(bool cleared_soft_refs) {
449+
ZHeap::heap()->handle_alloc_stalling_for_old(cleared_soft_refs);
446450
}
447451

448-
void ZDriverMajor::handle_alloc_stalls() const {
449-
handle_alloc_stalling_for_old();
452+
void ZDriverMajor::handle_alloc_stalls(bool cleared_soft_refs) const {
453+
handle_alloc_stalling_for_old(cleared_soft_refs);
450454
}
451455

452456
void ZDriverMajor::run_thread() {
@@ -461,6 +465,10 @@ void ZDriverMajor::run_thread() {
461465

462466
abortpoint();
463467

468+
// Set up soft reference policy
469+
const bool clear_soft_refs = should_clear_soft_references(request.cause());
470+
ZGeneration::old()->set_soft_reference_policy(clear_soft_refs);
471+
464472
// Run GC
465473
gc(request);
466474

@@ -470,7 +478,7 @@ void ZDriverMajor::run_thread() {
470478
_port.ack();
471479

472480
// Handle allocation stalls
473-
handle_alloc_stalls();
481+
handle_alloc_stalls(clear_soft_refs);
474482

475483
ZBreakpoint::at_after_gc();
476484
}

src/hotspot/share/gc/z/zDriver.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ class ZDriverMajor : public ZDriver {
112112

113113
void collect_old();
114114
void gc(const ZDriverRequest& request);
115-
void handle_alloc_stalls() const;
115+
void handle_alloc_stalls(bool cleared_soft_refs) const;
116116

117117
protected:
118118
virtual void run_thread();

src/hotspot/share/gc/z/zHeap.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ class ZHeap {
111111
bool is_alloc_stalling() const;
112112
bool is_alloc_stalling_for_old() const;
113113
void handle_alloc_stalling_for_young();
114-
void handle_alloc_stalling_for_old();
114+
void handle_alloc_stalling_for_old(bool cleared_soft_refs);
115115

116116
// Continuations
117117
bool is_allocating(zaddress addr) const;

src/hotspot/share/gc/z/zHeap.inline.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,8 @@ inline void ZHeap::handle_alloc_stalling_for_young() {
8686
_page_allocator.handle_alloc_stalling_for_young();
8787
}
8888

89-
inline void ZHeap::handle_alloc_stalling_for_old() {
90-
_page_allocator.handle_alloc_stalling_for_old();
89+
inline void ZHeap::handle_alloc_stalling_for_old(bool cleared_soft_refs) {
90+
_page_allocator.handle_alloc_stalling_for_old(cleared_soft_refs);
9191
}
9292

9393
inline bool ZHeap::is_oop(uintptr_t addr) const {

src/hotspot/share/gc/z/zPageAllocator.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -985,9 +985,11 @@ void ZPageAllocator::handle_alloc_stalling_for_young() {
985985
restart_gc();
986986
}
987987

988-
void ZPageAllocator::handle_alloc_stalling_for_old() {
988+
void ZPageAllocator::handle_alloc_stalling_for_old(bool cleared_soft_refs) {
989989
ZLocker<ZLock> locker(&_lock);
990-
notify_out_of_memory();
990+
if (cleared_soft_refs) {
991+
notify_out_of_memory();
992+
}
991993
restart_gc();
992994
}
993995

src/hotspot/share/gc/z/zPageAllocator.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ class ZPageAllocator {
163163
bool is_alloc_stalling() const;
164164
bool is_alloc_stalling_for_old() const;
165165
void handle_alloc_stalling_for_young();
166-
void handle_alloc_stalling_for_old();
166+
void handle_alloc_stalling_for_old(bool cleared_soft_refs);
167167

168168
void threads_do(ThreadClosure* tc) const;
169169
};

0 commit comments

Comments
 (0)