8150390: Move rs length sampling data to the sampling thread

Reviewed-by: drwhite, jwilhelm
This commit is contained in:
Mikael Gerdin 2016-02-25 11:20:03 +01:00
parent 4f6dba1568
commit 167ce92545
7 changed files with 32 additions and 74 deletions

View file

@ -1400,7 +1400,6 @@ bool G1CollectedHeap::do_full_collection(bool explicit_gc,
JavaThread::dirty_card_queue_set().abandon_logs();
assert(dirty_card_queue_set().completed_buffers_num() == 0, "DCQS should be empty");
_young_list->reset_sampled_info();
// At this point there should be no regions in the
// entire heap tagged as young.
assert(check_young_list_empty(true /* check_heap */),
@ -3390,8 +3389,6 @@ G1CollectedHeap::do_collection_pause_at_safepoint(double target_pause_time_ms) {
clear_cset_fast_test();
_young_list->reset_sampled_info();
// Don't check the whole heap at this point as the
// GC alloc regions from this pause have been tagged
// as survivors and moved on to the survivor list.
@ -5188,8 +5185,8 @@ public:
bool success() { return _success; }
};
bool G1CollectedHeap::check_young_list_empty(bool check_heap, bool check_sample) {
bool ret = _young_list->check_list_empty(check_sample);
bool G1CollectedHeap::check_young_list_empty(bool check_heap) {
bool ret = _young_list->check_list_empty();
if (check_heap) {
NoYoungRegionsClosure closure;

View file

@ -1333,8 +1333,7 @@ public:
return _young_list->check_list_well_formed();
}
bool check_young_list_empty(bool check_heap,
bool check_sample = true);
bool check_young_list_empty(bool check_heap);
// *** Stuff related to concurrent marking. It's not clear to me that so
// many of these need to be public.

View file

@ -787,10 +787,9 @@ double G1CollectorPolicy::predict_survivor_regions_evac_time() const {
return survivor_regions_evac_time;
}
void G1CollectorPolicy::revise_young_list_target_length_if_necessary() {
void G1CollectorPolicy::revise_young_list_target_length_if_necessary(size_t rs_lengths) {
guarantee( adaptive_young_list_length(), "should not call this otherwise" );
size_t rs_lengths = _g1->young_list()->sampled_rs_lengths();
if (rs_lengths > _rs_lengths_prediction) {
// add 10% to avoid having to recalculate often
size_t rs_lengths_prediction = rs_lengths * 1100 / 1000;

View file

@ -471,7 +471,7 @@ public:
// Check the current value of the young list RSet lengths and
// compare it against the last prediction. If the current value is
// higher, recalculate the young list target length prediction.
void revise_young_list_target_length_if_necessary();
void revise_young_list_target_length_if_necessary(size_t rs_lengths);
// This should be called after the heap is resized.
void record_new_heap_size(uint new_number_of_regions);

View file

@ -26,6 +26,8 @@
#include "gc/g1/g1CollectedHeap.inline.hpp"
#include "gc/g1/g1CollectorPolicy.hpp"
#include "gc/g1/g1YoungRemSetSamplingThread.hpp"
#include "gc/g1/heapRegion.inline.hpp"
#include "gc/g1/heapRegionRemSet.hpp"
#include "gc/g1/suspendibleThreadSet.hpp"
#include "runtime/mutexLocker.hpp"
@ -100,22 +102,35 @@ void G1YoungRemSetSamplingThread::sample_young_list_rs_lengths() {
G1CollectorPolicy* g1p = g1h->g1_policy();
if (g1p->adaptive_young_list_length()) {
int regions_visited = 0;
g1h->young_list()->rs_length_sampling_init();
while (g1h->young_list()->rs_length_sampling_more()) {
g1h->young_list()->rs_length_sampling_next();
HeapRegion* hr = g1h->young_list()->first_region();
size_t sampled_rs_lengths = 0;
while (hr != NULL) {
size_t rs_length = hr->rem_set()->occupied();
sampled_rs_lengths += rs_length;
// The current region may not yet have been added to the
// incremental collection set (it gets added when it is
// retired as the current allocation region).
if (hr->in_collection_set()) {
// Update the collection set policy information for this region
g1p->update_incremental_cset_info(hr, rs_length);
}
++regions_visited;
// we try to yield every time we visit 10 regions
if (regions_visited == 10) {
if (sts.should_yield()) {
sts.yield();
// we just abandon the iteration
break;
// A gc may have occurred and our sampling data is stale and further
// traversal of the young list is unsafe
return;
}
regions_visited = 0;
}
hr = hr->get_next_young_region();
}
g1p->revise_young_list_target_length_if_necessary();
g1p->revise_young_list_target_length_if_necessary(sampled_rs_lengths);
}
}

View file

@ -33,9 +33,9 @@
#include "utilities/ostream.hpp"
YoungList::YoungList(G1CollectedHeap* g1h) :
_g1h(g1h), _head(NULL), _length(0), _last_sampled_rs_lengths(0),
_g1h(g1h), _head(NULL), _length(0),
_survivor_head(NULL), _survivor_tail(NULL), _survivor_length(0) {
guarantee(check_list_empty(false), "just making sure...");
guarantee(check_list_empty(), "just making sure...");
}
void YoungList::push_region(HeapRegion *hr) {
@ -86,9 +86,7 @@ void YoungList::empty_list() {
_survivor_tail = NULL;
_survivor_length = 0;
_last_sampled_rs_lengths = 0;
assert(check_list_empty(false), "just making sure...");
assert(check_list_empty(), "just making sure...");
}
bool YoungList::check_list_well_formed() {
@ -119,17 +117,13 @@ bool YoungList::check_list_well_formed() {
return ret;
}
bool YoungList::check_list_empty(bool check_sample) {
bool YoungList::check_list_empty() {
bool ret = true;
if (_length != 0) {
log_error(gc, verify)("### YOUNG LIST should have 0 length, not %u", _length);
ret = false;
}
if (check_sample && _last_sampled_rs_lengths != 0) {
log_error(gc, verify)("### YOUNG LIST has non-zero last sampled RS lengths");
ret = false;
}
if (_head != NULL) {
log_error(gc, verify)("### YOUNG LIST does not have a NULL head");
ret = false;
@ -141,38 +135,6 @@ bool YoungList::check_list_empty(bool check_sample) {
return ret;
}
void
YoungList::rs_length_sampling_init() {
_sampled_rs_lengths = 0;
_curr = _head;
}
bool
YoungList::rs_length_sampling_more() {
return _curr != NULL;
}
void
YoungList::rs_length_sampling_next() {
assert( _curr != NULL, "invariant" );
size_t rs_length = _curr->rem_set()->occupied();
_sampled_rs_lengths += rs_length;
// The current region may not yet have been added to the
// incremental collection set (it gets added when it is
// retired as the current allocation region).
if (_curr->in_collection_set()) {
// Update the collection set policy information for this region
_g1h->g1_policy()->update_incremental_cset_info(_curr, rs_length);
}
_curr = _curr->get_next_young_region();
if (_curr == NULL) {
_last_sampled_rs_lengths = _sampled_rs_lengths;
}
}
void
YoungList::reset_auxilary_lists() {
guarantee( is_empty(), "young list should be empty" );

View file

@ -37,14 +37,9 @@ private:
HeapRegion* _survivor_head;
HeapRegion* _survivor_tail;
HeapRegion* _curr;
uint _length;
uint _survivor_length;
size_t _last_sampled_rs_lengths;
size_t _sampled_rs_lengths;
void empty_list(HeapRegion* list);
public:
@ -72,15 +67,6 @@ public:
return (size_t) survivor_length() * HeapRegion::GrainBytes;
}
void rs_length_sampling_init();
bool rs_length_sampling_more();
void rs_length_sampling_next();
void reset_sampled_info() {
_last_sampled_rs_lengths = 0;
}
size_t sampled_rs_lengths() { return _last_sampled_rs_lengths; }
// for development purposes
void reset_auxilary_lists();
void clear() { _head = NULL; _length = 0; }
@ -97,7 +83,7 @@ public:
// debugging
bool check_list_well_formed();
bool check_list_empty(bool check_sample = true);
bool check_list_empty();
void print();
};