mirror of
https://github.com/openjdk/jdk.git
synced 2026-01-28 12:09:14 +00:00
8337658: ZGC: Move soft reference handling out of the driver loop function
Reviewed-by: gli, aboldtch, eosterlund
This commit is contained in:
parent
8e0d0190ed
commit
9cbf685b0b
@ -230,8 +230,8 @@ void ZDriverMinor::terminate() {
|
||||
_port.send_async(request);
|
||||
}
|
||||
|
||||
static bool should_clear_soft_references(GCCause::Cause cause) {
|
||||
// Clear soft references if implied by the GC cause
|
||||
static bool should_clear_all_soft_references(GCCause::Cause cause) {
|
||||
// Clear all soft references if implied by the GC cause
|
||||
switch (cause) {
|
||||
case GCCause::_wb_full_gc:
|
||||
case GCCause::_metadata_GC_clear_soft_refs:
|
||||
@ -259,12 +259,12 @@ static bool should_clear_soft_references(GCCause::Cause cause) {
|
||||
break;
|
||||
}
|
||||
|
||||
// Clear soft references if threads are stalled waiting for an old collection
|
||||
// Clear all soft references if threads are stalled waiting for an old collection
|
||||
if (ZHeap::heap()->is_alloc_stalling_for_old()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Don't clear
|
||||
// Don't clear all soft references
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -302,13 +302,17 @@ static bool should_preclean_young(GCCause::Cause cause) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// It is important that when soft references are cleared, we also pre-clean the young
|
||||
// generation, as we might otherwise throw premature OOM. Therefore, all causes that
|
||||
// trigger soft ref cleaning must also trigger pre-cleaning of young gen. If allocations
|
||||
// stalled when checking for soft ref cleaning, then since we hold the driver locker all
|
||||
// the way until we check for young gen pre-cleaning, we can be certain that we should
|
||||
// We clear all soft references as a last-ditch effort to collect memory
|
||||
// before throwing an OOM. Therefore it is important that when the GC policy
|
||||
// is to clear all soft references, that we also pre-clean the young
|
||||
// generation, as we might otherwise throw premature OOM.
|
||||
//
|
||||
// Therefore, all causes that trigger all soft ref clearing must also trigger
|
||||
// pre-cleaning of young gen. If allocations stalled when checking for all
|
||||
// soft ref clearing, then since we hold the driver locker all the way until
|
||||
// we check for young gen pre-cleaning, we can be certain that we should
|
||||
// catch that above and perform young gen pre-cleaning.
|
||||
assert(!should_clear_soft_references(cause), "Clearing soft references without pre-cleaning young gen");
|
||||
assert(!should_clear_all_soft_references(cause), "Clearing all soft references without pre-cleaning young gen");
|
||||
|
||||
return false;
|
||||
}
|
||||
@ -395,6 +399,10 @@ public:
|
||||
// Select number of worker threads to use
|
||||
ZGeneration::young()->set_active_workers(request.young_nworkers());
|
||||
ZGeneration::old()->set_active_workers(request.old_nworkers());
|
||||
|
||||
// Set up soft reference policy
|
||||
const bool clear_all = should_clear_all_soft_references(request.cause());
|
||||
ZGeneration::old()->set_soft_reference_policy(clear_all);
|
||||
}
|
||||
|
||||
~ZDriverScopeMajor() {
|
||||
@ -444,12 +452,13 @@ void ZDriverMajor::gc(const ZDriverRequest& request) {
|
||||
collect_old();
|
||||
}
|
||||
|
||||
static void handle_alloc_stalling_for_old(bool cleared_soft_refs) {
|
||||
ZHeap::heap()->handle_alloc_stalling_for_old(cleared_soft_refs);
|
||||
static void handle_alloc_stalling_for_old() {
|
||||
const bool cleared_all = ZGeneration::old()->uses_clear_all_soft_reference_policy();
|
||||
ZHeap::heap()->handle_alloc_stalling_for_old(cleared_all);
|
||||
}
|
||||
|
||||
void ZDriverMajor::handle_alloc_stalls(bool cleared_soft_refs) const {
|
||||
handle_alloc_stalling_for_old(cleared_soft_refs);
|
||||
void ZDriverMajor::handle_alloc_stalls() const {
|
||||
handle_alloc_stalling_for_old();
|
||||
}
|
||||
|
||||
void ZDriverMajor::run_thread() {
|
||||
@ -464,10 +473,6 @@ void ZDriverMajor::run_thread() {
|
||||
|
||||
abortpoint();
|
||||
|
||||
// Set up soft reference policy
|
||||
const bool clear_soft_refs = should_clear_soft_references(request.cause());
|
||||
ZGeneration::old()->set_soft_reference_policy(clear_soft_refs);
|
||||
|
||||
// Run GC
|
||||
gc(request);
|
||||
|
||||
@ -477,7 +482,7 @@ void ZDriverMajor::run_thread() {
|
||||
_port.ack();
|
||||
|
||||
// Handle allocation stalls
|
||||
handle_alloc_stalls(clear_soft_refs);
|
||||
handle_alloc_stalls();
|
||||
|
||||
ZBreakpoint::at_after_gc();
|
||||
}
|
||||
|
||||
@ -112,7 +112,7 @@ private:
|
||||
|
||||
void collect_old();
|
||||
void gc(const ZDriverRequest& request);
|
||||
void handle_alloc_stalls(bool cleared_soft_refs) const;
|
||||
void handle_alloc_stalls() const;
|
||||
|
||||
protected:
|
||||
virtual void run_thread();
|
||||
|
||||
@ -1286,6 +1286,10 @@ void ZGenerationOld::set_soft_reference_policy(bool clear) {
|
||||
_reference_processor.set_soft_reference_policy(clear);
|
||||
}
|
||||
|
||||
bool ZGenerationOld::uses_clear_all_soft_reference_policy() const {
|
||||
return _reference_processor.uses_clear_all_soft_reference_policy();
|
||||
}
|
||||
|
||||
class ZRendezvousHandshakeClosure : public HandshakeClosure {
|
||||
public:
|
||||
ZRendezvousHandshakeClosure()
|
||||
|
||||
@ -309,6 +309,7 @@ public:
|
||||
// Reference processing
|
||||
ReferenceDiscoverer* reference_discoverer();
|
||||
void set_soft_reference_policy(bool clear);
|
||||
bool uses_clear_all_soft_reference_policy() const;
|
||||
|
||||
uint total_collections_at_start() const;
|
||||
|
||||
|
||||
@ -86,8 +86,8 @@ inline void ZHeap::handle_alloc_stalling_for_young() {
|
||||
_page_allocator.handle_alloc_stalling_for_young();
|
||||
}
|
||||
|
||||
inline void ZHeap::handle_alloc_stalling_for_old(bool cleared_soft_refs) {
|
||||
_page_allocator.handle_alloc_stalling_for_old(cleared_soft_refs);
|
||||
inline void ZHeap::handle_alloc_stalling_for_old(bool cleared_all_soft_refs) {
|
||||
_page_allocator.handle_alloc_stalling_for_old(cleared_all_soft_refs);
|
||||
}
|
||||
|
||||
inline bool ZHeap::is_oop(uintptr_t addr) const {
|
||||
|
||||
@ -985,9 +985,9 @@ void ZPageAllocator::handle_alloc_stalling_for_young() {
|
||||
restart_gc();
|
||||
}
|
||||
|
||||
void ZPageAllocator::handle_alloc_stalling_for_old(bool cleared_soft_refs) {
|
||||
void ZPageAllocator::handle_alloc_stalling_for_old(bool cleared_all_soft_refs) {
|
||||
ZLocker<ZLock> locker(&_lock);
|
||||
if (cleared_soft_refs) {
|
||||
if (cleared_all_soft_refs) {
|
||||
notify_out_of_memory();
|
||||
}
|
||||
restart_gc();
|
||||
|
||||
@ -113,7 +113,7 @@ static void list_append(zaddress& head, zaddress& tail, zaddress reference) {
|
||||
ZReferenceProcessor::ZReferenceProcessor(ZWorkers* workers)
|
||||
: _workers(workers),
|
||||
_soft_reference_policy(nullptr),
|
||||
_clear_all_soft_refs(false),
|
||||
_uses_clear_all_soft_reference_policy(false),
|
||||
_encountered_count(),
|
||||
_discovered_count(),
|
||||
_enqueued_count(),
|
||||
@ -121,13 +121,13 @@ ZReferenceProcessor::ZReferenceProcessor(ZWorkers* workers)
|
||||
_pending_list(zaddress::null),
|
||||
_pending_list_tail(zaddress::null) {}
|
||||
|
||||
void ZReferenceProcessor::set_soft_reference_policy(bool clear) {
|
||||
void ZReferenceProcessor::set_soft_reference_policy(bool clear_all_soft_references) {
|
||||
static AlwaysClearPolicy always_clear_policy;
|
||||
static LRUMaxHeapPolicy lru_max_heap_policy;
|
||||
|
||||
_clear_all_soft_refs = clear;
|
||||
_uses_clear_all_soft_reference_policy = clear_all_soft_references;
|
||||
|
||||
if (clear) {
|
||||
if (clear_all_soft_references) {
|
||||
_soft_reference_policy = &always_clear_policy;
|
||||
} else {
|
||||
_soft_reference_policy = &lru_max_heap_policy;
|
||||
@ -136,6 +136,10 @@ void ZReferenceProcessor::set_soft_reference_policy(bool clear) {
|
||||
_soft_reference_policy->setup();
|
||||
}
|
||||
|
||||
bool ZReferenceProcessor::uses_clear_all_soft_reference_policy() const {
|
||||
return _uses_clear_all_soft_reference_policy;
|
||||
}
|
||||
|
||||
bool ZReferenceProcessor::is_inactive(zaddress reference, oop referent, ReferenceType type) const {
|
||||
if (type == REF_FINAL) {
|
||||
// A FinalReference is inactive if its next field is non-null. An application can't
|
||||
@ -440,7 +444,7 @@ public:
|
||||
void ZReferenceProcessor::process_references() {
|
||||
ZStatTimerOld timer(ZSubPhaseConcurrentReferencesProcess);
|
||||
|
||||
if (_clear_all_soft_refs) {
|
||||
if (_uses_clear_all_soft_reference_policy) {
|
||||
log_info(gc, ref)("Clearing All SoftReferences");
|
||||
}
|
||||
|
||||
|
||||
@ -41,7 +41,7 @@ private:
|
||||
|
||||
ZWorkers* const _workers;
|
||||
ReferencePolicy* _soft_reference_policy;
|
||||
bool _clear_all_soft_refs;
|
||||
bool _uses_clear_all_soft_reference_policy;
|
||||
ZPerWorker<Counters> _encountered_count;
|
||||
ZPerWorker<Counters> _discovered_count;
|
||||
ZPerWorker<Counters> _enqueued_count;
|
||||
@ -69,7 +69,9 @@ private:
|
||||
public:
|
||||
ZReferenceProcessor(ZWorkers* workers);
|
||||
|
||||
void set_soft_reference_policy(bool clear);
|
||||
void set_soft_reference_policy(bool clear_all_soft_references);
|
||||
bool uses_clear_all_soft_reference_policy() const;
|
||||
|
||||
void reset_statistics();
|
||||
|
||||
virtual bool discover_reference(oop reference, ReferenceType type);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user