Skip to content
This repository has been archived by the owner. It is now read-only.
Permalink
Browse files
8252645: Change time measurements in G1ServiceThread to only account …
…remembered set work

Reviewed-by: ayang, tschatzl
  • Loading branch information
kstefanj committed Nov 27, 2020
1 parent a3eec39 commit ee99686b28b91fbd3729324879182d5e90a59cca
@@ -482,27 +482,6 @@ class G1RemSetScanState : public CHeapObj<mtGC> {
}
};

G1RemSet::G1RemSet(G1CollectedHeap* g1h,
G1CardTable* ct,
G1HotCardCache* hot_card_cache) :
_scan_state(new G1RemSetScanState()),
_prev_period_summary(false),
_g1h(g1h),
_ct(ct),
_g1p(_g1h->policy()),
_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;
@@ -537,6 +516,19 @@ class G1YoungRemSetSamplingClosure : public HeapRegionClosure {

// Task handling young gen remembered set sampling.
class G1RemSetSamplingTask : public G1ServiceTask {
// Helper to account virtual time.
class VTimer {
double _start;
public:
VTimer() : _start(os::elapsedVTime()) { }
double duration() { return os::elapsedVTime() - _start; }
};

double _vtime_accum; // Accumulated virtual time.
void update_vtime_accum(double duration) {
_vtime_accum += duration;
}

// 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
@@ -551,6 +543,7 @@ class G1RemSetSamplingTask : public G1ServiceTask {
void sample_young_list_rs_length(SuspendibleThreadSetJoiner* sts){
G1CollectedHeap* g1h = G1CollectedHeap::heap();
G1Policy* policy = g1h->policy();
VTimer vtime;

if (policy->use_adaptive_young_list_length()) {
G1YoungRemSetSamplingClosure cl(sts);
@@ -562,6 +555,7 @@ class G1RemSetSamplingTask : public G1ServiceTask {
policy->revise_young_list_target_length_if_necessary(cl.sampled_rs_length());
}
}
update_vtime_accum(vtime.duration());
}

// To avoid extensive rescheduling if the task is executed a bit early. The task is
@@ -596,14 +590,48 @@ class G1RemSetSamplingTask : public G1ServiceTask {
sample_young_list_rs_length(&sts);
schedule(G1ConcRefinementServiceIntervalMillis);
}

double vtime_accum() {
// Only report vtime if supported by the os.
if (!os::supports_vtime()) {
return 0.0;
}
return _vtime_accum;
}
};

G1RemSet::G1RemSet(G1CollectedHeap* g1h,
G1CardTable* ct,
G1HotCardCache* hot_card_cache) :
_scan_state(new G1RemSetScanState()),
_prev_period_summary(false),
_g1h(g1h),
_ct(ct),
_g1p(_g1h->policy()),
_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);
}

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);
}

double G1RemSet::sampling_task_vtime() {
assert(_sampling_task != NULL, "Must have been initialized");
return _sampling_task->vtime_accum();
}

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

@@ -67,7 +67,7 @@ class G1RemSet: public CHeapObj<mtGC> {
G1CardTable* _ct;
G1Policy* _g1p;
G1HotCardCache* _hot_card_cache;
G1ServiceTask* _sampling_task;
G1RemSetSamplingTask* _sampling_task;

void print_merge_heap_roots_stats();

@@ -87,6 +87,9 @@ class G1RemSet: public CHeapObj<mtGC> {
// Initialize and schedule young remembered set sampling task.
void initialize_sampling_task(G1ServiceThread* thread);

// Accumulated vtime used by the sampling task.
double sampling_task_vtime();

// 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,
@@ -30,7 +30,6 @@
#include "gc/g1/g1DirtyCardQueue.hpp"
#include "gc/g1/g1RemSet.hpp"
#include "gc/g1/g1RemSetSummary.hpp"
#include "gc/g1/g1ServiceThread.hpp"
#include "gc/g1/heapRegion.hpp"
#include "gc/g1/heapRegionRemSet.hpp"
#include "memory/allocation.inline.hpp"
@@ -53,7 +52,7 @@ void G1RemSetSummary::update() {
g1h->concurrent_refine()->threads_do(&collector);
_num_coarsenings = HeapRegionRemSet::n_coarsenings();

set_service_thread_vtime(g1h->service_thread()->vtime_accum());
set_sampling_task_vtime(g1h->rem_set()->sampling_task_vtime());
}

void G1RemSetSummary::set_rs_thread_vtime(uint thread, double value) {
@@ -72,7 +71,7 @@ G1RemSetSummary::G1RemSetSummary(bool should_update) :
_num_coarsenings(0),
_num_vtimes(G1ConcurrentRefine::max_num_threads()),
_rs_threads_vtimes(NEW_C_HEAP_ARRAY(double, _num_vtimes, mtGC)),
_service_thread_vtime(0.0f) {
_sampling_task_vtime(0.0f) {

memset(_rs_threads_vtimes, 0, sizeof(double) * _num_vtimes);

@@ -93,7 +92,7 @@ void G1RemSetSummary::set(G1RemSetSummary* other) {

memcpy(_rs_threads_vtimes, other->_rs_threads_vtimes, sizeof(double) * _num_vtimes);

set_service_thread_vtime(other->service_thread_vtime());
set_sampling_task_vtime(other->sampling_task_vtime());
}

void G1RemSetSummary::subtract_from(G1RemSetSummary* other) {
@@ -106,7 +105,7 @@ void G1RemSetSummary::subtract_from(G1RemSetSummary* other) {
set_rs_thread_vtime(i, other->rs_thread_vtime(i) - rs_thread_vtime(i));
}

_service_thread_vtime = other->service_thread_vtime() - _service_thread_vtime;
_sampling_task_vtime = other->sampling_task_vtime() - _sampling_task_vtime;
}

class RegionTypeCounter {
@@ -327,8 +326,8 @@ void G1RemSetSummary::print_on(outputStream* out) {
out->print(" %5.2f", rs_thread_vtime(i));
}
out->cr();
out->print_cr(" Service thread time (s)");
out->print_cr(" %5.2f", service_thread_vtime());
out->print_cr(" Sampling task time (ms)");
out->print_cr(" %5.3f", sampling_task_vtime() * MILLIUNITS);

HRRSStatsIter blk;
G1CollectedHeap::heap()->heap_region_iterate(&blk);
@@ -38,11 +38,11 @@ class G1RemSetSummary {
size_t _num_vtimes;
double* _rs_threads_vtimes;

double _service_thread_vtime;
double _sampling_task_vtime;

void set_rs_thread_vtime(uint thread, double value);
void set_service_thread_vtime(double value) {
_service_thread_vtime = value;
void set_sampling_task_vtime(double value) {
_sampling_task_vtime = value;
}

// update this summary with current data from various places
@@ -62,8 +62,8 @@ class G1RemSetSummary {

double rs_thread_vtime(uint thread) const;

double service_thread_vtime() const {
return _service_thread_vtime;
double sampling_task_vtime() const {
return _sampling_task_vtime;
}

size_t num_coarsenings() const {
@@ -102,8 +102,7 @@ G1ServiceThread::G1ServiceThread() :
true,
Monitor::_safepoint_check_never),
_task_queue(),
_periodic_gc_task(new G1PeriodicGCTask("Periodic GC Task")),
_vtime_accum(0) {
_periodic_gc_task(new G1PeriodicGCTask("Periodic GC Task")) {
set_name("G1 Service");
create_and_start();
}
@@ -215,8 +214,6 @@ void G1ServiceThread::run_task(G1ServiceTask* task) {
}

void G1ServiceThread::run_service() {
double vtime_start = os::elapsedVTime();

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

@@ -226,11 +223,6 @@ void G1ServiceThread::run_service() {
run_task(task);
}

if (os::supports_vtime()) {
_vtime_accum = (os::elapsedVTime() - vtime_start);
} else {
_vtime_accum = 0.0;
}
sleep_before_next_cycle();
}

@@ -107,8 +107,6 @@ class G1ServiceThread: public ConcurrentGCThread {

G1PeriodicGCTask* _periodic_gc_task;

double _vtime_accum; // Accumulated virtual time.

void run_service();
void stop_service();

@@ -133,7 +131,6 @@ class G1ServiceThread: public ConcurrentGCThread {
G1ServiceThread();
~G1ServiceThread();

double vtime_accum() { return _vtime_accum; }
// Register a task with the service thread and schedule it. If
// no delay is specified the task is scheduled to run directly.
void register_task(G1ServiceTask* task, jlong delay = 0);

0 comments on commit ee99686

Please sign in to comment.