From 2f8da3e9ff60e5cb2a3fdf57dbcb67f513b9c2c2 Mon Sep 17 00:00:00 2001 From: Mathieu Chartier Date: Tue, 15 Apr 2014 15:37:02 -0700 Subject: [PATCH] Decrease target utilization for foreground apps. GC time in FormulaEvaluationActions.EvaluateAndApplyChanges goes from 26.1s to 23.2s. Benchmark score goes down ~50 in FormulaEvaluationActions.EvaluateAndApplyChanges, and up ~50 in GenericCalcActions.MemAllocTest. Bug: 8788501 Change-Id: I412af1205f8b67e70a12237c990231ea62167bc0 --- runtime/gc/heap.cc | 36 +++++++++++++++++++++++++----------- runtime/gc/heap.h | 13 ++++++++++--- runtime/parsed_options.cc | 5 +++++ runtime/parsed_options.h | 1 + runtime/runtime.cc | 1 + 5 files changed, 42 insertions(+), 14 deletions(-) diff --git a/runtime/gc/heap.cc b/runtime/gc/heap.cc index 07d04551b..de7d0b85b 100644 --- a/runtime/gc/heap.cc +++ b/runtime/gc/heap.cc @@ -88,7 +88,8 @@ static constexpr bool kCompactZygote = kMovingCollector; static constexpr size_t kNonMovingSpaceCapacity = 64 * MB; Heap::Heap(size_t initial_size, size_t growth_limit, size_t min_free, size_t max_free, - double target_utilization, size_t capacity, const std::string& image_file_name, + double target_utilization, double foreground_heap_growth_multiplier, size_t capacity, + const std::string& image_file_name, CollectorType foreground_collector_type, CollectorType background_collector_type, size_t parallel_gc_threads, size_t conc_gc_threads, bool low_memory_mode, size_t long_pause_log_threshold, size_t long_gc_log_threshold, @@ -154,6 +155,7 @@ Heap::Heap(size_t initial_size, size_t growth_limit, size_t min_free, size_t max min_free_(min_free), max_free_(max_free), target_utilization_(target_utilization), + foreground_heap_growth_multiplier_(foreground_heap_growth_multiplier), total_wait_time_(0), total_allocation_time_(0), verify_object_mode_(kVerifyObjectModeDisabled), @@ -2524,22 +2526,33 @@ collector::GarbageCollector* Heap::FindCollectorByGcType(collector::GcType gc_ty return nullptr; } +double Heap::HeapGrowthMultiplier() const { + // If we don't care about pause times we are background, so return 1.0. + if (!CareAboutPauseTimes() || IsLowMemoryMode()) { + return 1.0; + } + return foreground_heap_growth_multiplier_; +} + void Heap::GrowForUtilization(collector::GarbageCollector* collector_ran) { // We know what our utilization is at this moment. // This doesn't actually resize any memory. It just lets the heap grow more when necessary. - const size_t bytes_allocated = GetBytesAllocated(); + const uint64_t bytes_allocated = GetBytesAllocated(); last_gc_size_ = bytes_allocated; last_gc_time_ns_ = NanoTime(); - size_t target_size; + uint64_t target_size; collector::GcType gc_type = collector_ran->GetGcType(); if (gc_type != collector::kGcTypeSticky) { // Grow the heap for non sticky GC. - target_size = bytes_allocated / GetTargetHeapUtilization(); - if (target_size > bytes_allocated + max_free_) { - target_size = bytes_allocated + max_free_; - } else if (target_size < bytes_allocated + min_free_) { - target_size = bytes_allocated + min_free_; - } + const float multiplier = HeapGrowthMultiplier(); // Use the multiplier to grow more for + // foreground. + intptr_t delta = bytes_allocated / GetTargetHeapUtilization() - bytes_allocated; + CHECK_GE(delta, 0); + target_size = bytes_allocated + delta * multiplier; + target_size = std::min(target_size, + bytes_allocated + static_cast(max_free_ * multiplier)); + target_size = std::max(target_size, + bytes_allocated + static_cast(min_free_ * multiplier)); native_need_to_run_finalization_ = true; next_gc_type_ = collector::kGcTypeSticky; } else { @@ -2564,7 +2577,7 @@ void Heap::GrowForUtilization(collector::GarbageCollector* collector_ran) { if (bytes_allocated + max_free_ < max_allowed_footprint_) { target_size = bytes_allocated + max_free_; } else { - target_size = std::max(bytes_allocated, max_allowed_footprint_); + target_size = std::max(bytes_allocated, static_cast(max_allowed_footprint_)); } } if (!ignore_max_footprint_) { @@ -2588,7 +2601,8 @@ void Heap::GrowForUtilization(collector::GarbageCollector* collector_ran) { // Start a concurrent GC when we get close to the estimated remaining bytes. When the // allocation rate is very high, remaining_bytes could tell us that we should start a GC // right away. - concurrent_start_bytes_ = std::max(max_allowed_footprint_ - remaining_bytes, bytes_allocated); + concurrent_start_bytes_ = std::max(max_allowed_footprint_ - remaining_bytes, + static_cast(bytes_allocated)); } } } diff --git a/runtime/gc/heap.h b/runtime/gc/heap.h index 874357f03..35724e3b5 100644 --- a/runtime/gc/heap.h +++ b/runtime/gc/heap.h @@ -132,9 +132,8 @@ class Heap { static constexpr size_t kDefaultLongPauseLogThreshold = MsToNs(5); static constexpr size_t kDefaultLongGCLogThreshold = MsToNs(100); static constexpr size_t kDefaultTLABSize = 256 * KB; - - // Default target utilization. static constexpr double kDefaultTargetUtilization = 0.5; + static constexpr double kDefaultHeapGrowthMultiplier = 2.0; // Used so that we don't overflow the allocation time atomic integer. static constexpr size_t kTimeAdjust = 1024; @@ -148,7 +147,8 @@ class Heap { // image_file_names names specify Spaces to load based on // ImageWriter output. explicit Heap(size_t initial_size, size_t growth_limit, size_t min_free, - size_t max_free, double target_utilization, size_t capacity, + size_t max_free, double target_utilization, + double foreground_heap_growth_multiplier, size_t capacity, const std::string& original_image_file_name, CollectorType foreground_collector_type, CollectorType background_collector_type, size_t parallel_gc_threads, size_t conc_gc_threads, bool low_memory_mode, @@ -351,6 +351,10 @@ class Heap { return low_memory_mode_; } + // Returns the heap growth multiplier, this affects how much we grow the heap after a GC. + // Scales heap growth, min free, and max free. + double HeapGrowthMultiplier() const; + // Freed bytes can be negative in cases where we copy objects from a compacted space to a // free-list backed space. void RecordFree(ssize_t freed_objects, ssize_t freed_bytes); @@ -927,6 +931,9 @@ class Heap { // Target ideal heap utilization ratio double target_utilization_; + // How much more we grow the heap when we are a foreground app instead of background. + double foreground_heap_growth_multiplier_; + // Total time which mutators are paused or waiting for GC to complete. uint64_t total_wait_time_; diff --git a/runtime/parsed_options.cc b/runtime/parsed_options.cc index 29fe5365c..57d32bb47 100644 --- a/runtime/parsed_options.cc +++ b/runtime/parsed_options.cc @@ -131,6 +131,7 @@ bool ParsedOptions::Parse(const Runtime::Options& options, bool ignore_unrecogni heap_min_free_ = gc::Heap::kDefaultMinFree; heap_max_free_ = gc::Heap::kDefaultMaxFree; heap_target_utilization_ = gc::Heap::kDefaultTargetUtilization; + foreground_heap_growth_multiplier_ = gc::Heap::kDefaultHeapGrowthMultiplier; heap_growth_limit_ = 0; // 0 means no growth limit . // Default to number of processors minus one since the main GC thread also does work. parallel_gc_threads_ = sysconf(_SC_NPROCESSORS_CONF) - 1; @@ -314,6 +315,10 @@ bool ParsedOptions::Parse(const Runtime::Options& options, bool ignore_unrecogni if (!ParseDouble(option, '=', 0.1, 0.9, &heap_target_utilization_)) { return false; } + } else if (StartsWith(option, "-XX:ForegroundHeapGrowthMultiplier=")) { + if (!ParseDouble(option, '=', 0.1, 0.9, &foreground_heap_growth_multiplier_)) { + return false; + } } else if (StartsWith(option, "-XX:ParallelGCThreads=")) { if (!ParseUnsignedInteger(option, '=', ¶llel_gc_threads_)) { return false; diff --git a/runtime/parsed_options.h b/runtime/parsed_options.h index 126096a26..770e4ae56 100644 --- a/runtime/parsed_options.h +++ b/runtime/parsed_options.h @@ -54,6 +54,7 @@ class ParsedOptions { size_t heap_min_free_; size_t heap_max_free_; double heap_target_utilization_; + double foreground_heap_growth_multiplier_; unsigned int parallel_gc_threads_; unsigned int conc_gc_threads_; gc::CollectorType collector_type_; diff --git a/runtime/runtime.cc b/runtime/runtime.cc index 5c31d3573..eb0522ad0 100644 --- a/runtime/runtime.cc +++ b/runtime/runtime.cc @@ -564,6 +564,7 @@ bool Runtime::Init(const Options& raw_options, bool ignore_unrecognized) { options->heap_min_free_, options->heap_max_free_, options->heap_target_utilization_, + options->foreground_heap_growth_multiplier_, options->heap_maximum_size_, options->image_, options->collector_type_, -- 2.11.0