Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(636)

Unified Diff: src/heap.cc

Issue 2809032: Take survival rates of young objects into account when choosing old generation limits. (Closed)
Patch Set: throttle down Created 10 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/heap.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/heap.cc
diff --git a/src/heap.cc b/src/heap.cc
index f1ec56ce5a862ad7a6ae811f1391408335db802c..d0dbdb1eab2fcdad0c88ab0a987bb245bd0345d4 100644
--- a/src/heap.cc
+++ b/src/heap.cc
@@ -126,6 +126,13 @@ int Heap::always_allocate_scope_depth_ = 0;
int Heap::linear_allocation_scope_depth_ = 0;
int Heap::contexts_disposed_ = 0;
+int Heap::young_survivors_after_last_gc_ = 0;
+int Heap::high_survival_rate_period_length_ = 0;
+int Heap::survival_rate_ = 0;
+Heap::SurvivalRateTrend Heap::previous_survival_rate_trend_ = Heap::STABLE;
+Heap::SurvivalRateTrend Heap::survival_rate_trend_ = Heap::STABLE;
+bool Heap::bumped_old_gen_limits_ = false;
+
#ifdef DEBUG
bool Heap::allocation_allowed_ = true;
@@ -582,6 +589,29 @@ static void VerifyPageWatermarkValidity(PagedSpace* space,
}
#endif
+void Heap::UpdateSurvivalRateTrend(int start_new_space_size) {
+ double survival_rate =
+ (static_cast<double>(young_survivors_after_last_gc_) * 100) /
+ start_new_space_size;
+
+ if (survival_rate > kYoungSurvivalRateThreshold) {
+ high_survival_rate_period_length_++;
+ } else {
+ high_survival_rate_period_length_ = 0;
+ }
+
+ double survival_rate_diff = survival_rate_ - survival_rate;
+
+ if (survival_rate_diff > kYoungSurvivalRateAllowedDeviation) {
+ set_survival_rate_trend(DECREASING);
+ } else if (survival_rate_diff < -kYoungSurvivalRateAllowedDeviation) {
+ set_survival_rate_trend(INCREASING);
+ } else {
+ set_survival_rate_trend(STABLE);
+ }
+
+ survival_rate_ = survival_rate;
+}
void Heap::PerformGarbageCollection(AllocationSpace space,
GarbageCollector collector,
@@ -604,6 +634,8 @@ void Heap::PerformGarbageCollection(AllocationSpace space,
EnsureFromSpaceIsCommitted();
+ int start_new_space_size = Heap::new_space()->Size();
+
if (collector == MARK_COMPACTOR) {
if (FLAG_flush_code) {
// Flush all potentially unused code.
@@ -613,16 +645,50 @@ void Heap::PerformGarbageCollection(AllocationSpace space,
// Perform mark-sweep with optional compaction.
MarkCompact(tracer);
+ bool high_survival_rate_during_scavenges = IsHighSurvivalRate() &&
+ IsStableOrIncreasingSurvivalTrend();
+
+ UpdateSurvivalRateTrend(start_new_space_size);
+
int old_gen_size = PromotedSpaceSize();
old_gen_promotion_limit_ =
old_gen_size + Max(kMinimumPromotionLimit, old_gen_size / 3);
old_gen_allocation_limit_ =
old_gen_size + Max(kMinimumAllocationLimit, old_gen_size / 2);
+
+ if (high_survival_rate_during_scavenges &&
+ IsStableOrIncreasingSurvivalTrend()) {
+ // Stable high survival rates of young objects both during partial and
+ // full collection indicate that mutator is either building or modifying
+ // a structure with a long lifetime.
+ // In this case we aggressively raise old generation memory limits to
+ // postpone subsequent mark-sweep collection and thus trade memory
+ // space for the mutation speed.
+ old_gen_promotion_limit_ *= 2;
+ old_gen_allocation_limit_ *= 2;
+ bumped_old_gen_limits_ = true;
+ }
+
old_gen_exhausted_ = false;
} else {
tracer_ = tracer;
Scavenge();
tracer_ = NULL;
+
+ UpdateSurvivalRateTrend(start_new_space_size);
+
+ if (bumped_old_gen_limits_ &&
+ !IsHighSurvivalRate() &&
+ !IsIncreasingSurvivalTrend()) {
+ // We previously observed high survival rates in young space and decided
+ // to bump old space allocation limits to trade the space for the speed
+ // but now survival rates are dropping which indicates that mutator
+ // finished updating tenured data structure. So we can decrease old space
+ // limits to guarantee an early full GC cycle and reduce memory footprint.
+ old_gen_promotion_limit_ /= 2;
+ old_gen_allocation_limit_ /= 2;
+ bumped_old_gen_limits_ = false;
+ }
}
Counters::objs_since_last_young.Set(0);
« no previous file with comments | « src/heap.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698