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

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

Issue 2919023003: [heap] Scale max heap growing factor. (Closed)
Patch Set: rename 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 4175 matching lines...) Expand 10 before | Expand all | Expand 10 after
4186 bool Heap::HasHighFragmentation(size_t used, size_t committed) { 4186 bool Heap::HasHighFragmentation(size_t used, size_t committed) {
4187 const size_t kSlack = 16 * MB; 4187 const size_t kSlack = 16 * MB;
4188 // Fragmentation is high if committed > 2 * used + kSlack. 4188 // Fragmentation is high if committed > 2 * used + kSlack.
4189 // Rewrite the exression to avoid overflow. 4189 // Rewrite the exression to avoid overflow.
4190 DCHECK_GE(committed, used); 4190 DCHECK_GE(committed, used);
4191 return committed - used > used + kSlack; 4191 return committed - used > used + kSlack;
4192 } 4192 }
4193 4193
4194 bool Heap::ShouldOptimizeForMemoryUsage() { 4194 bool Heap::ShouldOptimizeForMemoryUsage() {
4195 return FLAG_optimize_for_size || isolate()->IsIsolateInBackground() || 4195 return FLAG_optimize_for_size || isolate()->IsIsolateInBackground() ||
4196 HighMemoryPressure() || IsLowMemoryDevice(); 4196 HighMemoryPressure();
4197 } 4197 }
4198 4198
4199 void Heap::ActivateMemoryReducerIfNeeded() { 4199 void Heap::ActivateMemoryReducerIfNeeded() {
4200 // Activate memory reducer when switching to background if 4200 // Activate memory reducer when switching to background if
4201 // - there was no mark compact since the start. 4201 // - there was no mark compact since the start.
4202 // - the committed memory can be potentially reduced. 4202 // - the committed memory can be potentially reduced.
4203 // 2 pages for the old, code, and map space + 1 page for new space. 4203 // 2 pages for the old, code, and map space + 1 page for new space.
4204 const int kMinCommittedMemory = 7 * Page::kPageSize; 4204 const int kMinCommittedMemory = 7 * Page::kPageSize;
4205 if (ms_count_ == 0 && CommittedMemory() > kMinCommittedMemory && 4205 if (ms_count_ == 0 && CommittedMemory() > kMinCommittedMemory &&
4206 isolate()->IsIsolateInBackground()) { 4206 isolate()->IsIsolateInBackground()) {
(...skipping 1217 matching lines...) Expand 10 before | Expand all | Expand 10 after
5424 // (Limit - Live) / mutator_speed = Limit * MU / (gc_speed * (1 - MU)) 5424 // (Limit - Live) / mutator_speed = Limit * MU / (gc_speed * (1 - MU))
5425 // (Limit - Live) = Limit * MU * mutator_speed / (gc_speed * (1 - MU)) 5425 // (Limit - Live) = Limit * MU * mutator_speed / (gc_speed * (1 - MU))
5426 // substitute R = gc_speed / mutator_speed 5426 // substitute R = gc_speed / mutator_speed
5427 // (Limit - Live) = Limit * MU / (R * (1 - MU)) 5427 // (Limit - Live) = Limit * MU / (R * (1 - MU))
5428 // substitute F = Limit / Live 5428 // substitute F = Limit / Live
5429 // F - 1 = F * MU / (R * (1 - MU)) 5429 // F - 1 = F * MU / (R * (1 - MU))
5430 // F - F * MU / (R * (1 - MU)) = 1 5430 // F - F * MU / (R * (1 - MU)) = 1
5431 // F * (1 - MU / (R * (1 - MU))) = 1 5431 // F * (1 - MU / (R * (1 - MU))) = 1
5432 // F * (R * (1 - MU) - MU) / (R * (1 - MU)) = 1 5432 // F * (R * (1 - MU) - MU) / (R * (1 - MU)) = 1
5433 // F = R * (1 - MU) / (R * (1 - MU) - MU) 5433 // F = R * (1 - MU) / (R * (1 - MU) - MU)
5434 double Heap::HeapGrowingFactor(double gc_speed, double mutator_speed) { 5434 double Heap::HeapGrowingFactor(double gc_speed, double mutator_speed,
5435 if (gc_speed == 0 || mutator_speed == 0) return kMaxHeapGrowingFactor; 5435 double max_factor) {
5436 DCHECK(max_factor >= kMinHeapGrowingFactor);
5437 DCHECK(max_factor <= kMaxHeapGrowingFactor);
5438 if (gc_speed == 0 || mutator_speed == 0) return max_factor;
5436 5439
5437 const double speed_ratio = gc_speed / mutator_speed; 5440 const double speed_ratio = gc_speed / mutator_speed;
5438 const double mu = kTargetMutatorUtilization; 5441 const double mu = kTargetMutatorUtilization;
5439 5442
5440 const double a = speed_ratio * (1 - mu); 5443 const double a = speed_ratio * (1 - mu);
5441 const double b = speed_ratio * (1 - mu) - mu; 5444 const double b = speed_ratio * (1 - mu) - mu;
5442 5445
5443 // The factor is a / b, but we need to check for small b first. 5446 // The factor is a / b, but we need to check for small b first.
5444 double factor = 5447 double factor = (a < b * max_factor) ? a / b : max_factor;
5445 (a < b * kMaxHeapGrowingFactor) ? a / b : kMaxHeapGrowingFactor; 5448 factor = Min(factor, max_factor);
5446 factor = Min(factor, kMaxHeapGrowingFactor);
5447 factor = Max(factor, kMinHeapGrowingFactor); 5449 factor = Max(factor, kMinHeapGrowingFactor);
5448 return factor; 5450 return factor;
5449 } 5451 }
5450 5452
5453 double Heap::MaxHeapGrowingFactor(size_t max_old_generation_size) {
5454 const double min_small_factor = 1.3;
5455 const double max_small_factor = 2.0;
5456 const double high_factor = 4.0;
5457
5458 size_t max_old_generation_size_in_mb = max_old_generation_size / MB;
5459 max_old_generation_size_in_mb =
5460 Max(max_old_generation_size_in_mb,
5461 static_cast<size_t>(kMinOldGenerationSize));
5462
5463 // If we are on a device with lots of memory, we allow a high heap
5464 // growing factor.
5465 if (max_old_generation_size_in_mb == kMaxOldGenerationSize) {
ulan 2017/06/09 08:39:43 Should it be >= instead of == ?
Hannes Payer (out of office) 2017/06/09 12:16:47 Done.
5466 return high_factor;
5467 }
5468
5469 DCHECK_GE(max_old_generation_size_in_mb, kMinOldGenerationSize);
5470 DCHECK_LT(max_old_generation_size_in_mb, kMaxOldGenerationSize);
5471
5472 // On smaller devices we linearly scale the factor: (X-A)/(B-A)*(D-C)+C
5473 double factor = (max_old_generation_size_in_mb - kMinOldGenerationSize) *
5474 (max_small_factor - min_small_factor) /
5475 (kMaxOldGenerationSize - 1 - kMinOldGenerationSize) +
ulan 2017/06/09 08:39:43 Why (-1) here?
Hannes Payer (out of office) 2017/06/09 12:16:47 I decided to do that because we would never reach
5476 min_small_factor;
5477 return factor;
5478 }
5479
5451 size_t Heap::CalculateOldGenerationAllocationLimit(double factor, 5480 size_t Heap::CalculateOldGenerationAllocationLimit(double factor,
5452 size_t old_gen_size) { 5481 size_t old_gen_size) {
5453 CHECK(factor > 1.0); 5482 CHECK(factor > 1.0);
5454 CHECK(old_gen_size > 0); 5483 CHECK(old_gen_size > 0);
5455 uint64_t limit = static_cast<uint64_t>(old_gen_size * factor); 5484 uint64_t limit = static_cast<uint64_t>(old_gen_size * factor);
5456 limit = Max(limit, static_cast<uint64_t>(old_gen_size) + 5485 limit = Max(limit, static_cast<uint64_t>(old_gen_size) +
5457 MinimumAllocationLimitGrowingStep()); 5486 MinimumAllocationLimitGrowingStep());
5458 limit += new_space_->Capacity(); 5487 limit += new_space_->Capacity();
5459 uint64_t halfway_to_the_max = 5488 uint64_t halfway_to_the_max =
5460 (static_cast<uint64_t>(old_gen_size) + max_old_generation_size_) / 2; 5489 (static_cast<uint64_t>(old_gen_size) + max_old_generation_size_) / 2;
5461 return static_cast<size_t>(Min(limit, halfway_to_the_max)); 5490 return static_cast<size_t>(Min(limit, halfway_to_the_max));
5462 } 5491 }
5463 5492
5464 size_t Heap::MinimumAllocationLimitGrowingStep() { 5493 size_t Heap::MinimumAllocationLimitGrowingStep() {
5465 const size_t kRegularAllocationLimitGrowingStep = 8; 5494 const size_t kRegularAllocationLimitGrowingStep = 8;
5466 const size_t kLowMemoryAllocationLimitGrowingStep = 2; 5495 const size_t kLowMemoryAllocationLimitGrowingStep = 2;
5467 size_t limit = (Page::kPageSize > MB ? Page::kPageSize : MB); 5496 size_t limit = (Page::kPageSize > MB ? Page::kPageSize : MB);
5468 return limit * (ShouldOptimizeForMemoryUsage() 5497 return limit * (ShouldOptimizeForMemoryUsage()
5469 ? kLowMemoryAllocationLimitGrowingStep 5498 ? kLowMemoryAllocationLimitGrowingStep
5470 : kRegularAllocationLimitGrowingStep); 5499 : kRegularAllocationLimitGrowingStep);
5471 } 5500 }
5472 5501
5473 void Heap::SetOldGenerationAllocationLimit(size_t old_gen_size, double gc_speed, 5502 void Heap::SetOldGenerationAllocationLimit(size_t old_gen_size, double gc_speed,
5474 double mutator_speed) { 5503 double mutator_speed) {
5475 double factor = HeapGrowingFactor(gc_speed, mutator_speed); 5504 double max_factor = MaxHeapGrowingFactor(max_old_generation_size_);
5505 double factor = HeapGrowingFactor(gc_speed, mutator_speed, max_factor);
5476 5506
5477 if (FLAG_trace_gc_verbose) { 5507 if (FLAG_trace_gc_verbose) {
5478 isolate_->PrintWithTimestamp( 5508 isolate_->PrintWithTimestamp(
5479 "Heap growing factor %.1f based on mu=%.3f, speed_ratio=%.f " 5509 "Heap growing factor %.1f based on mu=%.3f, speed_ratio=%.f "
5480 "(gc=%.f, mutator=%.f)\n", 5510 "(gc=%.f, mutator=%.f)\n",
5481 factor, kTargetMutatorUtilization, gc_speed / mutator_speed, gc_speed, 5511 factor, kTargetMutatorUtilization, gc_speed / mutator_speed, gc_speed,
5482 mutator_speed); 5512 mutator_speed);
5483 } 5513 }
5484 5514
5485 if (IsMemoryConstrainedDevice()) {
5486 factor = Min(factor, kMaxHeapGrowingFactorMemoryConstrained);
5487 }
5488
5489 if (memory_reducer_->ShouldGrowHeapSlowly() || 5515 if (memory_reducer_->ShouldGrowHeapSlowly() ||
5490 ShouldOptimizeForMemoryUsage()) { 5516 ShouldOptimizeForMemoryUsage()) {
5491 factor = Min(factor, kConservativeHeapGrowingFactor); 5517 factor = Min(factor, kConservativeHeapGrowingFactor);
5492 } 5518 }
5493 5519
5494 if (FLAG_stress_compaction || ShouldReduceMemory()) { 5520 if (FLAG_stress_compaction || ShouldReduceMemory()) {
5495 factor = kMinHeapGrowingFactor; 5521 factor = kMinHeapGrowingFactor;
5496 } 5522 }
5497 5523
5498 if (FLAG_heap_growing_percent > 0) { 5524 if (FLAG_heap_growing_percent > 0) {
5499 factor = 1.0 + FLAG_heap_growing_percent / 100.0; 5525 factor = 1.0 + FLAG_heap_growing_percent / 100.0;
5500 } 5526 }
5501 5527
5502 old_generation_allocation_limit_ = 5528 old_generation_allocation_limit_ =
5503 CalculateOldGenerationAllocationLimit(factor, old_gen_size); 5529 CalculateOldGenerationAllocationLimit(factor, old_gen_size);
5504 5530
5505 if (FLAG_trace_gc_verbose) { 5531 if (FLAG_trace_gc_verbose) {
5506 isolate_->PrintWithTimestamp( 5532 isolate_->PrintWithTimestamp(
5507 "Grow: old size: %" PRIuS " KB, new limit: %" PRIuS " KB (%.1f)\n", 5533 "Grow: old size: %" PRIuS " KB, new limit: %" PRIuS " KB (%.1f)\n",
5508 old_gen_size / KB, old_generation_allocation_limit_ / KB, factor); 5534 old_gen_size / KB, old_generation_allocation_limit_ / KB, factor);
5509 } 5535 }
5510 } 5536 }
5511 5537
5512 void Heap::DampenOldGenerationAllocationLimit(size_t old_gen_size, 5538 void Heap::DampenOldGenerationAllocationLimit(size_t old_gen_size,
5513 double gc_speed, 5539 double gc_speed,
5514 double mutator_speed) { 5540 double mutator_speed) {
5515 double factor = HeapGrowingFactor(gc_speed, mutator_speed); 5541 double max_factor = MaxHeapGrowingFactor(max_old_generation_size_);
5542 double factor = HeapGrowingFactor(gc_speed, mutator_speed, max_factor);
5516 size_t limit = CalculateOldGenerationAllocationLimit(factor, old_gen_size); 5543 size_t limit = CalculateOldGenerationAllocationLimit(factor, old_gen_size);
5517 if (limit < old_generation_allocation_limit_) { 5544 if (limit < old_generation_allocation_limit_) {
5518 if (FLAG_trace_gc_verbose) { 5545 if (FLAG_trace_gc_verbose) {
5519 isolate_->PrintWithTimestamp( 5546 isolate_->PrintWithTimestamp(
5520 "Dampen: old size: %" PRIuS " KB, old limit: %" PRIuS 5547 "Dampen: old size: %" PRIuS " KB, old limit: %" PRIuS
5521 " KB, " 5548 " KB, "
5522 "new limit: %" PRIuS " KB (%.1f)\n", 5549 "new limit: %" PRIuS " KB (%.1f)\n",
5523 old_gen_size / KB, old_generation_allocation_limit_ / KB, limit / KB, 5550 old_gen_size / KB, old_generation_allocation_limit_ / KB, limit / KB,
5524 factor); 5551 factor);
5525 } 5552 }
(...skipping 1081 matching lines...) Expand 10 before | Expand all | Expand 10 after
6607 case LO_SPACE: 6634 case LO_SPACE:
6608 return "LO_SPACE"; 6635 return "LO_SPACE";
6609 default: 6636 default:
6610 UNREACHABLE(); 6637 UNREACHABLE();
6611 } 6638 }
6612 return NULL; 6639 return NULL;
6613 } 6640 }
6614 6641
6615 } // namespace internal 6642 } // namespace internal
6616 } // namespace v8 6643 } // 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