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

Unified Diff: src/heap/heap.cc

Issue 1163143009: Compute the heap growing factor based on mutator utilization and allocation throughput. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Comments Created 5 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
« src/heap/gc-tracer.cc ('K') | « src/heap/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/heap.cc
diff --git a/src/heap/heap.cc b/src/heap/heap.cc
index f2783cf48297e0c26e35cb2169153e008e02e301..01d05e3857be5467987ce81781bbb97c857ebc38 100644
--- a/src/heap/heap.cc
+++ b/src/heap/heap.cc
@@ -1219,7 +1219,9 @@ bool Heap::PerformGarbageCollection(
old_gen_exhausted_ = false;
old_generation_size_configured_ = true;
// This should be updated before PostGarbageCollectionProcessing, which can
- // cause another GC.
+ // cause another GC. Take into account the objects promoted during GC.
+ old_generation_allocation_counter_ +=
+ static_cast<size_t>(promoted_objects_size_);
old_generation_size_at_last_gc_ = PromotedSpaceSizeOfObjects();
} else {
Scavenge();
@@ -1261,9 +1263,12 @@ bool Heap::PerformGarbageCollection(
// Register the amount of external allocated memory.
amount_of_external_allocated_memory_at_last_global_gc_ =
amount_of_external_allocated_memory_;
- SetOldGenerationAllocationLimit(
- PromotedSpaceSizeOfObjects(),
- tracer()->CurrentAllocationThroughputInBytesPerMillisecond());
+ double gc_speed = tracer()->CombinedMarkCompactSpeedInBytesPerMillisecond();
+ double mutator_speed = static_cast<double>(
+ tracer()
+ ->CurrentOldGenerationAllocationThroughputInBytesPerMillisecond());
+ intptr_t old_gen_size = PromotedSpaceSizeOfObjects();
+ SetOldGenerationAllocationLimit(old_gen_size, gc_speed, mutator_speed);
}
{
@@ -5286,6 +5291,48 @@ int64_t Heap::PromotedExternalMemorySize() {
}
+const double Heap::kMinHeapGrowingFactor = 1.1;
+const double Heap::kMaxHeapGrowingFactor = 4.0;
+const double Heap::kMaxHeapGrowingFactorMemoryConstrained = 2.0;
+const double Heap::kMaxHeapGrowingFactorIdle = 1.5;
+const double Heap::kTargetMutatorUtilization = 0.97;
+
+
+// Given GC speed in bytes per ms, the allocation throughput in bytes per ms
+// (mutator speed), this functions returns the heap growing factor that will
+// achive the kTargetMutatorUtilisation if the GC speed and the mutator speed
+// remain the same until the next GC. For details and explanation see
+// https://goo.gl/LLGvBs.
Hannes Payer (out of office) 2015/06/11 01:33:57 Instead of posting a link, can we add the necessar
ulan 2015/06/11 08:49:37 Done.
+double Heap::HeapGrowingFactor(double gc_speed, double mutator_speed) {
+ double max_factor = kMaxHeapGrowingFactor;
+ // We set the old generation growing factor to 2 to grow the heap slower on
+ // memory-constrained devices.
+ if (max_old_generation_size_ <= kMaxOldSpaceSizeMediumMemoryDevice) {
Hannes Payer (out of office) 2015/06/11 01:33:57 If we would not access max_old_generation_size_, t
ulan 2015/06/11 08:49:37 Done. The first function to be unit-tested in Heap
+ max_factor = kMaxHeapGrowingFactorMemoryConstrained;
+ }
+
+ if (gc_speed == 0 || mutator_speed == 0) return max_factor;
+
+ const double speed_ratio = gc_speed / mutator_speed;
+ const double mu = kTargetMutatorUtilization;
+
+ const double a = speed_ratio * (1 - mu);
+ const double b = speed_ratio * (1 - mu) - mu;
+
+ // The factor is a / b, but we need to check for small b first.
+ double factor = (a < b * max_factor) ? a / b : max_factor;
+ factor = Min(factor, max_factor);
+ factor = Max(factor, kMinHeapGrowingFactor);
+ if (FLAG_trace_gc_verbose) {
+ PrintIsolate(isolate_,
+ "Heap growing factor %.1f based on mu=%.3f, speed_ratio=%.f "
+ "(gc=%.f, mutator=%.f)\n",
+ factor, mu, speed_ratio, gc_speed, mutator_speed);
+ }
+ return factor;
+}
+
+
intptr_t Heap::CalculateOldGenerationAllocationLimit(double factor,
intptr_t old_gen_size) {
CHECK(factor > 1.0);
@@ -5298,52 +5345,20 @@ intptr_t Heap::CalculateOldGenerationAllocationLimit(double factor,
}
-void Heap::SetOldGenerationAllocationLimit(
- intptr_t old_gen_size, size_t current_allocation_throughput) {
-// Allocation throughput on Android devices is typically lower than on
-// non-mobile devices.
-#if V8_OS_ANDROID
- const size_t kHighThroughput = 2500;
- const size_t kLowThroughput = 250;
-#else
- const size_t kHighThroughput = 10000;
- const size_t kLowThroughput = 1000;
-#endif
- const double min_scaling_factor = 1.1;
- const double max_scaling_factor = 1.5;
- double max_factor = 4;
- const double idle_max_factor = 1.5;
- // We set the old generation growing factor to 2 to grow the heap slower on
- // memory-constrained devices.
- if (max_old_generation_size_ <= kMaxOldSpaceSizeMediumMemoryDevice) {
- max_factor = 2;
- }
-
- double factor;
- double idle_factor;
- if (current_allocation_throughput == 0 ||
- current_allocation_throughput >= kHighThroughput) {
- factor = max_factor;
- } else if (current_allocation_throughput <= kLowThroughput) {
- factor = min_scaling_factor;
- } else {
- // Compute factor using linear interpolation between points
- // (kHighThroughput, max_scaling_factor) and (kLowThroughput, min_factor).
- factor = min_scaling_factor +
- (current_allocation_throughput - kLowThroughput) *
- (max_scaling_factor - min_scaling_factor) /
- (kHighThroughput - kLowThroughput);
- }
+void Heap::SetOldGenerationAllocationLimit(intptr_t old_gen_size,
+ double gc_speed,
+ double mutator_speed) {
+ double factor = HeapGrowingFactor(gc_speed, mutator_speed);
if (FLAG_stress_compaction ||
mark_compact_collector()->reduce_memory_footprint_) {
- factor = min_scaling_factor;
+ factor = kMinHeapGrowingFactor;
}
// TODO(hpayer): Investigate if idle_old_generation_allocation_limit_ is still
// needed after taking the allocation rate for the old generation limit into
// account.
- idle_factor = Min(factor, idle_max_factor);
+ double idle_factor = Min(factor, kMaxHeapGrowingFactorIdle);
old_generation_allocation_limit_ =
CalculateOldGenerationAllocationLimit(factor, old_gen_size);
« src/heap/gc-tracer.cc ('K') | « src/heap/heap.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698