@@ -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
452456void 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 }
0 commit comments