< prev index next >
src/hotspot/share/gc/g1/g1Policy.cpp
Print this page
rev 58105 : [mq]: 8236073-softmaxheapsize
@@ -30,10 +30,11 @@
#include "gc/g1/g1CollectionSetCandidates.hpp"
#include "gc/g1/g1ConcurrentMark.hpp"
#include "gc/g1/g1ConcurrentMarkThread.inline.hpp"
#include "gc/g1/g1ConcurrentRefine.hpp"
#include "gc/g1/g1CollectionSetChooser.hpp"
+#include "gc/g1/g1HeapSizingPolicy.hpp"
#include "gc/g1/g1HeterogeneousHeapPolicy.hpp"
#include "gc/g1/g1HotCardCache.hpp"
#include "gc/g1/g1IHOPControl.hpp"
#include "gc/g1/g1GCPhaseTimes.hpp"
#include "gc/g1/g1Policy.hpp"
@@ -74,10 +75,11 @@
_pending_cards_at_prev_gc_end(0),
_total_mutator_refined_cards(0),
_total_concurrent_refined_cards(0),
_total_concurrent_refinement_time(),
_bytes_allocated_in_old_since_last_gc(0),
+ _minimum_desired_bytes_after_last_cm(0),
_initial_mark_to_mixed(),
_collection_set(NULL),
_g1h(NULL),
_phase_times(new G1GCPhaseTimes(gc_timer, ParallelGCThreads)),
_mark_remark_start_sec(0),
@@ -1093,10 +1095,25 @@
log_debug(gc, ergo)("Do not initiate concurrent cycle (concurrent cycle already in progress)");
}
}
}
+void G1Policy::determine_desired_bytes_after_concurrent_mark() {
+ size_t cur_used_bytes = _g1h->non_young_capacity_bytes();
+
+ size_t overall_target_capacity = _g1h->heap_sizing_policy()->target_heap_capacity(cur_used_bytes, MinHeapFreeRatio);
+
+ size_t desired_bytes_after_concurrent_mark = _g1h->policy()->desired_bytes_after_concurrent_mark(cur_used_bytes);
+
+ _minimum_desired_bytes_after_last_cm = MIN2(desired_bytes_after_concurrent_mark, overall_target_capacity);
+
+ log_debug(gc, ergo, heap)("Expansion amount after remark used: " SIZE_FORMAT " "
+ "minimum_desired_capacity " SIZE_FORMAT " desired_bytes_after_concurrent_mark: " SIZE_FORMAT " "
+ "minimum_desired_bytes_after_concurrent_mark " SIZE_FORMAT,
+ cur_used_bytes, overall_target_capacity, desired_bytes_after_concurrent_mark, _minimum_desired_bytes_after_last_cm);
+}
+
void G1Policy::record_concurrent_mark_cleanup_end() {
G1CollectionSetCandidates* candidates = G1CollectionSetChooser::build(_g1h->workers(), _g1h->num_regions());
_collection_set->set_candidates(candidates);
bool mixed_gc_pending = next_gc_should_be_mixed("request mixed gcs", "request young-only gcs");
@@ -1105,10 +1122,12 @@
abort_time_to_mixed_tracking();
}
collector_state()->set_in_young_gc_before_mixed(mixed_gc_pending);
collector_state()->set_mark_or_rebuild_in_progress(false);
+ determine_desired_bytes_after_concurrent_mark();
+
double end_sec = os::elapsedTime();
double elapsed_time_ms = (end_sec - _mark_cleanup_start_sec) * 1000.0;
_analytics->report_concurrent_mark_cleanup_times_ms(elapsed_time_ms);
_analytics->append_prev_collection_pause_end_ms(elapsed_time_ms);
@@ -1197,26 +1216,32 @@
bool G1Policy::next_gc_should_be_mixed(const char* true_action_str,
const char* false_action_str) const {
G1CollectionSetCandidates* candidates = _collection_set->candidates();
- if (candidates->is_empty()) {
+ if (candidates == NULL || candidates->is_empty()) {
+ if (false_action_str != NULL) {
log_debug(gc, ergo)("%s (candidate old regions not available)", false_action_str);
+ }
return false;
}
// Is the amount of uncollected reclaimable space above G1HeapWastePercent?
size_t reclaimable_bytes = candidates->remaining_reclaimable_bytes();
double reclaimable_percent = reclaimable_bytes_percent(reclaimable_bytes);
double threshold = (double) G1HeapWastePercent;
if (reclaimable_percent <= threshold) {
+ if (false_action_str != NULL) {
log_debug(gc, ergo)("%s (reclaimable percentage not over threshold). candidate old regions: %u reclaimable: " SIZE_FORMAT " (%1.2f) threshold: " UINTX_FORMAT,
false_action_str, candidates->num_remaining(), reclaimable_bytes, reclaimable_percent, G1HeapWastePercent);
+ }
return false;
}
+ if (true_action_str != NULL) {
log_debug(gc, ergo)("%s (candidate old regions available). candidate old regions: %u reclaimable: " SIZE_FORMAT " (%1.2f) threshold: " UINTX_FORMAT,
true_action_str, candidates->num_remaining(), reclaimable_bytes, reclaimable_percent, G1HeapWastePercent);
+ }
return true;
}
uint G1Policy::calc_min_old_cset_length() const {
// The min old CSet region bound is based on the maximum desired
@@ -1409,5 +1434,12 @@
// Don't clear the survivor list handles until the start of
// the next evacuation pause - we need it in order to re-tag
// the survivor regions from this evacuation pause as 'young'
// at the start of the next.
}
+
+size_t G1Policy::desired_bytes_after_concurrent_mark(size_t used_bytes) {
+ size_t minimum_desired_buffer_size = _ihop_control->predict_unrestrained_buffer_size();
+ return minimum_desired_buffer_size != 0 ?
+ minimum_desired_buffer_size :
+ _young_list_max_length * HeapRegion::GrainBytes + _reserve_regions * HeapRegion::GrainBytes + used_bytes;
+}
< prev index next >