Skip to content
Permalink
Browse files
8254999: Move G1RemSetSamplingTask to more appropriate location
Reviewed-by: tschatzl, ayang
  • Loading branch information
kstefanj committed Nov 24, 2020
1 parent 695117f commit 1b7a61ff4a01608da64bdeb96b1936f876219425
Showing 5 changed files with 90 additions and 80 deletions.
@@ -1705,6 +1705,9 @@ jint G1CollectedHeap::initialize() {
return ecode;
}

// Initialize and schedule sampling task on service thread.
_rem_set->initialize_sampling_task(service_thread());

{
G1DirtyCardQueueSet& dcqs = G1BarrierSet::dirty_card_queue_set();
dcqs.set_process_cards_threshold(concurrent_refine()->yellow_zone());
@@ -35,8 +35,10 @@
#include "gc/g1/g1GCPhaseTimes.hpp"
#include "gc/g1/g1HotCardCache.hpp"
#include "gc/g1/g1OopClosures.inline.hpp"
#include "gc/g1/g1Policy.hpp"
#include "gc/g1/g1RootClosures.hpp"
#include "gc/g1/g1RemSet.hpp"
#include "gc/g1/g1ServiceThread.hpp"
#include "gc/g1/g1SharedDirtyCardQueue.hpp"
#include "gc/g1/g1_globals.hpp"
#include "gc/g1/heapRegion.inline.hpp"
@@ -488,17 +490,95 @@ G1RemSet::G1RemSet(G1CollectedHeap* g1h,
_g1h(g1h),
_ct(ct),
_g1p(_g1h->policy()),
_hot_card_cache(hot_card_cache) {
_hot_card_cache(hot_card_cache),
_sampling_task(NULL) {
}

G1RemSet::~G1RemSet() {
delete _scan_state;
delete _sampling_task;
}

void G1RemSet::initialize(uint max_reserved_regions) {
_scan_state->initialize(max_reserved_regions);
}

class G1YoungRemSetSamplingClosure : public HeapRegionClosure {
SuspendibleThreadSetJoiner* _sts;
size_t _regions_visited;
size_t _sampled_rs_length;
public:
G1YoungRemSetSamplingClosure(SuspendibleThreadSetJoiner* sts) :
HeapRegionClosure(), _sts(sts), _regions_visited(0), _sampled_rs_length(0) { }

virtual bool do_heap_region(HeapRegion* r) {
size_t rs_length = r->rem_set()->occupied();
_sampled_rs_length += rs_length;

// Update the collection set policy information for this region
G1CollectedHeap::heap()->collection_set()->update_young_region_prediction(r, rs_length);

_regions_visited++;

if (_regions_visited == 10) {
if (_sts->should_yield()) {
_sts->yield();
// A gc may have occurred and our sampling data is stale and further
// traversal of the collection set is unsafe
return true;
}
_regions_visited = 0;
}
return false;
}

size_t sampled_rs_length() const { return _sampled_rs_length; }
};

// Task handling young gen remembered set sampling.
class G1RemSetSamplingTask : public G1ServiceTask {
// Sample the current length of remembered sets for young.
//
// At the end of the GC G1 determines the length of the young gen based on
// how much time the next GC can take, and when the next GC may occur
// according to the MMU.
//
// The assumption is that a significant part of the GC is spent on scanning
// the remembered sets (and many other components), so this thread constantly
// reevaluates the prediction for the remembered set scanning costs, and potentially
// G1Policy resizes the young gen. This may do a premature GC or even
// increase the young gen size to keep pause time length goal.
void sample_young_list_rs_length(){
SuspendibleThreadSetJoiner sts;
G1CollectedHeap* g1h = G1CollectedHeap::heap();
G1Policy* policy = g1h->policy();

if (policy->use_adaptive_young_list_length()) {
G1YoungRemSetSamplingClosure cl(&sts);

G1CollectionSet* g1cs = g1h->collection_set();
g1cs->iterate(&cl);

if (cl.is_complete()) {
policy->revise_young_list_target_length_if_necessary(cl.sampled_rs_length());
}
}
}

public:
G1RemSetSamplingTask(const char* name) : G1ServiceTask(name) { }
virtual void execute() {
sample_young_list_rs_length();
schedule(G1ConcRefinementServiceIntervalMillis);
}
};

void G1RemSet::initialize_sampling_task(G1ServiceThread* thread) {
assert(_sampling_task == NULL, "Sampling task already initialized");
_sampling_task = new G1RemSetSamplingTask("Remembered Set Sampling Task");
thread->register_task(_sampling_task);
}

// Helper class to scan and detect ranges of cards that need to be scanned on the
// card table.
class G1CardTableScanner : public StackObj {
@@ -49,6 +49,8 @@ class G1ParScanThreadState;
class G1ParScanThreadStateSet;
class G1Policy;
class G1ScanCardClosure;
class G1ServiceTask;
class G1ServiceThread;
class HeapRegionClaimer;

// A G1RemSet in which each heap region has a rem set that records the
@@ -65,6 +67,7 @@ class G1RemSet: public CHeapObj<mtGC> {
G1CardTable* _ct;
G1Policy* _g1p;
G1HotCardCache* _hot_card_cache;
G1ServiceTask* _sampling_task;

void print_merge_heap_roots_stats();

@@ -81,6 +84,9 @@ class G1RemSet: public CHeapObj<mtGC> {
G1HotCardCache* hot_card_cache);
~G1RemSet();

// Initialize and schedule young remembered set sampling task.
void initialize_sampling_task(G1ServiceThread* thread);

// Scan all cards in the non-collection set regions that potentially contain
// references into the current whole collection set.
void scan_heap_roots(G1ParScanThreadState* pss,
@@ -24,14 +24,9 @@

#include "precompiled.hpp"
#include "gc/g1/g1CollectedHeap.inline.hpp"
#include "gc/g1/g1CollectionSet.hpp"
#include "gc/g1/g1ConcurrentMark.inline.hpp"
#include "gc/g1/g1ConcurrentMarkThread.inline.hpp"
#include "gc/g1/g1Policy.hpp"
#include "gc/g1/g1ServiceThread.hpp"
#include "gc/g1/heapRegion.inline.hpp"
#include "gc/g1/heapRegionRemSet.hpp"
#include "gc/shared/suspendibleThreadSet.hpp"
#include "memory/universe.hpp"
#include "runtime/mutexLocker.hpp"
#include "runtime/os.hpp"
@@ -100,91 +95,20 @@ class G1PeriodicGCTask : public G1ServiceTask {
}
};

class G1YoungRemSetSamplingClosure : public HeapRegionClosure {
SuspendibleThreadSetJoiner* _sts;
size_t _regions_visited;
size_t _sampled_rs_length;
public:
G1YoungRemSetSamplingClosure(SuspendibleThreadSetJoiner* sts) :
HeapRegionClosure(), _sts(sts), _regions_visited(0), _sampled_rs_length(0) { }

virtual bool do_heap_region(HeapRegion* r) {
size_t rs_length = r->rem_set()->occupied();
_sampled_rs_length += rs_length;

// Update the collection set policy information for this region
G1CollectedHeap::heap()->collection_set()->update_young_region_prediction(r, rs_length);

_regions_visited++;

if (_regions_visited == 10) {
if (_sts->should_yield()) {
_sts->yield();
// A gc may have occurred and our sampling data is stale and further
// traversal of the collection set is unsafe
return true;
}
_regions_visited = 0;
}
return false;
}

size_t sampled_rs_length() const { return _sampled_rs_length; }
};

// Task handling young gen remembered set sampling.
class G1RemSetSamplingTask : public G1ServiceTask {
// Sample the current length of remembered sets for young.
//
// At the end of the GC G1 determines the length of the young gen based on
// how much time the next GC can take, and when the next GC may occur
// according to the MMU.
//
// The assumption is that a significant part of the GC is spent on scanning
// the remembered sets (and many other components), so this thread constantly
// reevaluates the prediction for the remembered set scanning costs, and potentially
// G1Policy resizes the young gen. This may do a premature GC or even
// increase the young gen size to keep pause time length goal.
void sample_young_list_rs_length(){
SuspendibleThreadSetJoiner sts;
G1CollectedHeap* g1h = G1CollectedHeap::heap();
G1Policy* policy = g1h->policy();

if (policy->use_adaptive_young_list_length()) {
G1YoungRemSetSamplingClosure cl(&sts);

G1CollectionSet* g1cs = g1h->collection_set();
g1cs->iterate(&cl);

if (cl.is_complete()) {
policy->revise_young_list_target_length_if_necessary(cl.sampled_rs_length());
}
}
}
public:
G1RemSetSamplingTask(const char* name) : G1ServiceTask(name) { }
virtual void execute() {
sample_young_list_rs_length();
schedule(G1ConcRefinementServiceIntervalMillis);
}
};

G1ServiceThread::G1ServiceThread() :
ConcurrentGCThread(),
_monitor(Mutex::nonleaf,
"G1ServiceThread monitor",
true,
Monitor::_safepoint_check_never),
_task_queue(),
_remset_task(new G1RemSetSamplingTask("Remembered Set Sampling Task")),
_periodic_gc_task(new G1PeriodicGCTask("Periodic GC Task")),
_vtime_accum(0) {
set_name("G1 Service");
create_and_start();
}

G1ServiceThread::~G1ServiceThread() {
delete _remset_task;
delete _periodic_gc_task;
}

@@ -295,7 +219,6 @@ void G1ServiceThread::run_service() {

// Register the tasks handled by the service thread.
register_task(_periodic_gc_task);
register_task(_remset_task);

while (!should_terminate()) {
G1ServiceTask* task = pop_due_task();
@@ -29,7 +29,6 @@
#include "runtime/mutex.hpp"

class G1PeriodicGCTask;
class G1RemSetSamplingTask;
class G1ServiceTaskQueue;
class G1ServiceThread;

@@ -106,7 +105,6 @@ class G1ServiceThread: public ConcurrentGCThread {
Monitor _monitor;
G1ServiceTaskQueue _task_queue;

G1RemSetSamplingTask* _remset_task;
G1PeriodicGCTask* _periodic_gc_task;

double _vtime_accum; // Accumulated virtual time.

1 comment on commit 1b7a61f

@openjdk-notifier
Copy link

@openjdk-notifier openjdk-notifier bot commented on 1b7a61f Nov 24, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.