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

Side by Side Diff: src/heap/heap.cc

Issue 2919023003: [heap] Scale max heap growing factor. (Closed)
Patch Set: tests Created 3 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 unified diff | Download patch
« no previous file with comments | « src/heap/heap.h ('k') | test/unittests/heap/heap-unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/heap/heap.h" 5 #include "src/heap/heap.h"
6 6
7 #include <unordered_map> 7 #include <unordered_map>
8 #include <unordered_set> 8 #include <unordered_set>
9 9
10 #include "src/accessors.h" 10 #include "src/accessors.h"
(...skipping 4166 matching lines...) Expand 10 before | Expand all | Expand 10 after
4177 bool Heap::HasHighFragmentation(size_t used, size_t committed) { 4177 bool Heap::HasHighFragmentation(size_t used, size_t committed) {
4178 const size_t kSlack = 16 * MB; 4178 const size_t kSlack = 16 * MB;
4179 // Fragmentation is high if committed > 2 * used + kSlack. 4179 // Fragmentation is high if committed > 2 * used + kSlack.
4180 // Rewrite the exression to avoid overflow. 4180 // Rewrite the exression to avoid overflow.
4181 DCHECK_GE(committed, used); 4181 DCHECK_GE(committed, used);
4182 return committed - used > used + kSlack; 4182 return committed - used > used + kSlack;
4183 } 4183 }
4184 4184
4185 bool Heap::ShouldOptimizeForMemoryUsage() { 4185 bool Heap::ShouldOptimizeForMemoryUsage() {
4186 return FLAG_optimize_for_size || isolate()->IsIsolateInBackground() || 4186 return FLAG_optimize_for_size || isolate()->IsIsolateInBackground() ||
4187 HighMemoryPressure() || IsLowMemoryDevice(); 4187 HighMemoryPressure();
4188 } 4188 }
4189 4189
4190 void Heap::ActivateMemoryReducerIfNeeded() { 4190 void Heap::ActivateMemoryReducerIfNeeded() {
4191 // Activate memory reducer when switching to background if 4191 // Activate memory reducer when switching to background if
4192 // - there was no mark compact since the start. 4192 // - there was no mark compact since the start.
4193 // - the committed memory can be potentially reduced. 4193 // - the committed memory can be potentially reduced.
4194 // 2 pages for the old, code, and map space + 1 page for new space. 4194 // 2 pages for the old, code, and map space + 1 page for new space.
4195 const int kMinCommittedMemory = 7 * Page::kPageSize; 4195 const int kMinCommittedMemory = 7 * Page::kPageSize;
4196 if (ms_count_ == 0 && CommittedMemory() > kMinCommittedMemory && 4196 if (ms_count_ == 0 && CommittedMemory() > kMinCommittedMemory &&
4197 isolate()->IsIsolateInBackground()) { 4197 isolate()->IsIsolateInBackground()) {
(...skipping 1219 matching lines...) Expand 10 before | Expand all | Expand 10 after
5417 // (Limit - Live) / mutator_speed = Limit * MU / (gc_speed * (1 - MU)) 5417 // (Limit - Live) / mutator_speed = Limit * MU / (gc_speed * (1 - MU))
5418 // (Limit - Live) = Limit * MU * mutator_speed / (gc_speed * (1 - MU)) 5418 // (Limit - Live) = Limit * MU * mutator_speed / (gc_speed * (1 - MU))
5419 // substitute R = gc_speed / mutator_speed 5419 // substitute R = gc_speed / mutator_speed
5420 // (Limit - Live) = Limit * MU / (R * (1 - MU)) 5420 // (Limit - Live) = Limit * MU / (R * (1 - MU))
5421 // substitute F = Limit / Live 5421 // substitute F = Limit / Live
5422 // F - 1 = F * MU / (R * (1 - MU)) 5422 // F - 1 = F * MU / (R * (1 - MU))
5423 // F - F * MU / (R * (1 - MU)) = 1 5423 // F - F * MU / (R * (1 - MU)) = 1
5424 // F * (1 - MU / (R * (1 - MU))) = 1 5424 // F * (1 - MU / (R * (1 - MU))) = 1
5425 // F * (R * (1 - MU) - MU) / (R * (1 - MU)) = 1 5425 // F * (R * (1 - MU) - MU) / (R * (1 - MU)) = 1
5426 // F = R * (1 - MU) / (R * (1 - MU) - MU) 5426 // F = R * (1 - MU) / (R * (1 - MU) - MU)
5427 double Heap::HeapGrowingFactor(double gc_speed, double mutator_speed) { 5427 double Heap::HeapGrowingFactor(double gc_speed, double mutator_speed,
5428 if (gc_speed == 0 || mutator_speed == 0) return kMaxHeapGrowingFactor; 5428 double max_factor) {
5429 DCHECK(max_factor >= kMinHeapGrowingFactor);
5430 DCHECK(max_factor <= kMaxHeapGrowingFactor);
5431 if (gc_speed == 0 || mutator_speed == 0) return max_factor;
5429 5432
5430 const double speed_ratio = gc_speed / mutator_speed; 5433 const double speed_ratio = gc_speed / mutator_speed;
5431 const double mu = kTargetMutatorUtilization; 5434 const double mu = kTargetMutatorUtilization;
5432 5435
5433 const double a = speed_ratio * (1 - mu); 5436 const double a = speed_ratio * (1 - mu);
5434 const double b = speed_ratio * (1 - mu) - mu; 5437 const double b = speed_ratio * (1 - mu) - mu;
5435 5438
5436 // The factor is a / b, but we need to check for small b first. 5439 // The factor is a / b, but we need to check for small b first.
5437 double factor = 5440 double factor = (a < b * max_factor) ? a / b : max_factor;
5438 (a < b * kMaxHeapGrowingFactor) ? a / b : kMaxHeapGrowingFactor; 5441 factor = Min(factor, max_factor);
5439 factor = Min(factor, kMaxHeapGrowingFactor);
5440 factor = Max(factor, kMinHeapGrowingFactor); 5442 factor = Max(factor, kMinHeapGrowingFactor);
5441 return factor; 5443 return factor;
5442 } 5444 }
5443 5445
5446 double Heap::MaxHeapGrowingFactor(size_t max_old_generation_size) {
5447 const double min_small_factor = 1.3;
5448 const double max_small_factor = 2.0;
5449 const double high_factor = 4.0;
5450
5451 size_t max_old_generation_size_in_mb = max_old_generation_size / MB;
5452 max_old_generation_size_in_mb =
5453 Max(max_old_generation_size_in_mb,
5454 static_cast<size_t>(kMinOldGenerationSize));
5455
5456 // If we are on a device with lots of memory, we allow a high heap
5457 // growing factor.
5458 if (max_old_generation_size_in_mb >= kMaxOldGenerationSize) {
5459 return high_factor;
5460 }
5461
5462 DCHECK_GE(max_old_generation_size_in_mb, kMinOldGenerationSize);
5463 DCHECK_LT(max_old_generation_size_in_mb, kMaxOldGenerationSize);
5464
5465 // On smaller devices we linearly scale the factor: (X-A)/(B-A)*(D-C)+C
5466 double factor = (max_old_generation_size_in_mb - kMinOldGenerationSize) *
5467 (max_small_factor - min_small_factor) /
5468 (kMaxOldGenerationSize - kMinOldGenerationSize) +
5469 min_small_factor;
5470 return factor;
5471 }
5472
5444 size_t Heap::CalculateOldGenerationAllocationLimit(double factor, 5473 size_t Heap::CalculateOldGenerationAllocationLimit(double factor,
5445 size_t old_gen_size) { 5474 size_t old_gen_size) {
5446 CHECK(factor > 1.0); 5475 CHECK(factor > 1.0);
5447 CHECK(old_gen_size > 0); 5476 CHECK(old_gen_size > 0);
5448 uint64_t limit = static_cast<uint64_t>(old_gen_size * factor); 5477 uint64_t limit = static_cast<uint64_t>(old_gen_size * factor);
5449 limit = Max(limit, static_cast<uint64_t>(old_gen_size) + 5478 limit = Max(limit, static_cast<uint64_t>(old_gen_size) +
5450 MinimumAllocationLimitGrowingStep()); 5479 MinimumAllocationLimitGrowingStep());
5451 limit += new_space_->Capacity(); 5480 limit += new_space_->Capacity();
5452 uint64_t halfway_to_the_max = 5481 uint64_t halfway_to_the_max =
5453 (static_cast<uint64_t>(old_gen_size) + max_old_generation_size_) / 2; 5482 (static_cast<uint64_t>(old_gen_size) + max_old_generation_size_) / 2;
5454 return static_cast<size_t>(Min(limit, halfway_to_the_max)); 5483 return static_cast<size_t>(Min(limit, halfway_to_the_max));
5455 } 5484 }
5456 5485
5457 size_t Heap::MinimumAllocationLimitGrowingStep() { 5486 size_t Heap::MinimumAllocationLimitGrowingStep() {
5458 const size_t kRegularAllocationLimitGrowingStep = 8; 5487 const size_t kRegularAllocationLimitGrowingStep = 8;
5459 const size_t kLowMemoryAllocationLimitGrowingStep = 2; 5488 const size_t kLowMemoryAllocationLimitGrowingStep = 2;
5460 size_t limit = (Page::kPageSize > MB ? Page::kPageSize : MB); 5489 size_t limit = (Page::kPageSize > MB ? Page::kPageSize : MB);
5461 return limit * (ShouldOptimizeForMemoryUsage() 5490 return limit * (ShouldOptimizeForMemoryUsage()
5462 ? kLowMemoryAllocationLimitGrowingStep 5491 ? kLowMemoryAllocationLimitGrowingStep
5463 : kRegularAllocationLimitGrowingStep); 5492 : kRegularAllocationLimitGrowingStep);
5464 } 5493 }
5465 5494
5466 void Heap::SetOldGenerationAllocationLimit(size_t old_gen_size, double gc_speed, 5495 void Heap::SetOldGenerationAllocationLimit(size_t old_gen_size, double gc_speed,
5467 double mutator_speed) { 5496 double mutator_speed) {
5468 double factor = HeapGrowingFactor(gc_speed, mutator_speed); 5497 double max_factor = MaxHeapGrowingFactor(max_old_generation_size_);
5498 double factor = HeapGrowingFactor(gc_speed, mutator_speed, max_factor);
5469 5499
5470 if (FLAG_trace_gc_verbose) { 5500 if (FLAG_trace_gc_verbose) {
5471 isolate_->PrintWithTimestamp( 5501 isolate_->PrintWithTimestamp(
5472 "Heap growing factor %.1f based on mu=%.3f, speed_ratio=%.f " 5502 "Heap growing factor %.1f based on mu=%.3f, speed_ratio=%.f "
5473 "(gc=%.f, mutator=%.f)\n", 5503 "(gc=%.f, mutator=%.f)\n",
5474 factor, kTargetMutatorUtilization, gc_speed / mutator_speed, gc_speed, 5504 factor, kTargetMutatorUtilization, gc_speed / mutator_speed, gc_speed,
5475 mutator_speed); 5505 mutator_speed);
5476 } 5506 }
5477 5507
5478 if (IsMemoryConstrainedDevice()) {
5479 factor = Min(factor, kMaxHeapGrowingFactorMemoryConstrained);
5480 }
5481
5482 if (memory_reducer_->ShouldGrowHeapSlowly() || 5508 if (memory_reducer_->ShouldGrowHeapSlowly() ||
5483 ShouldOptimizeForMemoryUsage()) { 5509 ShouldOptimizeForMemoryUsage()) {
5484 factor = Min(factor, kConservativeHeapGrowingFactor); 5510 factor = Min(factor, kConservativeHeapGrowingFactor);
5485 } 5511 }
5486 5512
5487 if (FLAG_stress_compaction || ShouldReduceMemory()) { 5513 if (FLAG_stress_compaction || ShouldReduceMemory()) {
5488 factor = kMinHeapGrowingFactor; 5514 factor = kMinHeapGrowingFactor;
5489 } 5515 }
5490 5516
5491 if (FLAG_heap_growing_percent > 0) { 5517 if (FLAG_heap_growing_percent > 0) {
5492 factor = 1.0 + FLAG_heap_growing_percent / 100.0; 5518 factor = 1.0 + FLAG_heap_growing_percent / 100.0;
5493 } 5519 }
5494 5520
5495 old_generation_allocation_limit_ = 5521 old_generation_allocation_limit_ =
5496 CalculateOldGenerationAllocationLimit(factor, old_gen_size); 5522 CalculateOldGenerationAllocationLimit(factor, old_gen_size);
5497 5523
5498 if (FLAG_trace_gc_verbose) { 5524 if (FLAG_trace_gc_verbose) {
5499 isolate_->PrintWithTimestamp( 5525 isolate_->PrintWithTimestamp(
5500 "Grow: old size: %" PRIuS " KB, new limit: %" PRIuS " KB (%.1f)\n", 5526 "Grow: old size: %" PRIuS " KB, new limit: %" PRIuS " KB (%.1f)\n",
5501 old_gen_size / KB, old_generation_allocation_limit_ / KB, factor); 5527 old_gen_size / KB, old_generation_allocation_limit_ / KB, factor);
5502 } 5528 }
5503 } 5529 }
5504 5530
5505 void Heap::DampenOldGenerationAllocationLimit(size_t old_gen_size, 5531 void Heap::DampenOldGenerationAllocationLimit(size_t old_gen_size,
5506 double gc_speed, 5532 double gc_speed,
5507 double mutator_speed) { 5533 double mutator_speed) {
5508 double factor = HeapGrowingFactor(gc_speed, mutator_speed); 5534 double max_factor = MaxHeapGrowingFactor(max_old_generation_size_);
5535 double factor = HeapGrowingFactor(gc_speed, mutator_speed, max_factor);
5509 size_t limit = CalculateOldGenerationAllocationLimit(factor, old_gen_size); 5536 size_t limit = CalculateOldGenerationAllocationLimit(factor, old_gen_size);
5510 if (limit < old_generation_allocation_limit_) { 5537 if (limit < old_generation_allocation_limit_) {
5511 if (FLAG_trace_gc_verbose) { 5538 if (FLAG_trace_gc_verbose) {
5512 isolate_->PrintWithTimestamp( 5539 isolate_->PrintWithTimestamp(
5513 "Dampen: old size: %" PRIuS " KB, old limit: %" PRIuS 5540 "Dampen: old size: %" PRIuS " KB, old limit: %" PRIuS
5514 " KB, " 5541 " KB, "
5515 "new limit: %" PRIuS " KB (%.1f)\n", 5542 "new limit: %" PRIuS " KB (%.1f)\n",
5516 old_gen_size / KB, old_generation_allocation_limit_ / KB, limit / KB, 5543 old_gen_size / KB, old_generation_allocation_limit_ / KB, limit / KB,
5517 factor); 5544 factor);
5518 } 5545 }
(...skipping 1081 matching lines...) Expand 10 before | Expand all | Expand 10 after
6600 case LO_SPACE: 6627 case LO_SPACE:
6601 return "LO_SPACE"; 6628 return "LO_SPACE";
6602 default: 6629 default:
6603 UNREACHABLE(); 6630 UNREACHABLE();
6604 } 6631 }
6605 return NULL; 6632 return NULL;
6606 } 6633 }
6607 6634
6608 } // namespace internal 6635 } // namespace internal
6609 } // namespace v8 6636 } // namespace v8
OLDNEW
« no previous file with comments | « src/heap/heap.h ('k') | test/unittests/heap/heap-unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698