Update concurrent start bytes when app switches from background
to foreground.
When app switches from background to foreground, the
concurrent start bytes value calculated in background is still
used until a GC occurs. This leads to a GC sooner than desired.
In order to prevent GC from happening too early and affecting
the hot start, We should update the concurrent start
bytes promptly when the process state changes
Bug: 249472594
Test: build
Signed-off-by: qiubowen <qiubowen@xiaomi.com>
Change-Id: I3fc6f5362c253af26792703ee38eab64605a80f2
diff --git a/runtime/gc/heap.cc b/runtime/gc/heap.cc
index 99c22ec..e840d92 100644
--- a/runtime/gc/heap.cc
+++ b/runtime/gc/heap.cc
@@ -336,6 +336,7 @@
// this one.
process_state_update_lock_("process state update lock", kPostMonitorLock),
min_foreground_target_footprint_(0),
+ min_foreground_concurrent_start_bytes_(0),
concurrent_start_bytes_(std::numeric_limits<size_t>::max()),
total_bytes_freed_ever_(0),
total_objects_freed_ever_(0),
@@ -1075,7 +1076,9 @@
min_foreground_target_footprint_,
std::memory_order_relaxed);
}
- min_foreground_target_footprint_ = 0;
+ if (IsGcConcurrent() && concurrent_start_bytes_ < min_foreground_concurrent_start_bytes_) {
+ concurrent_start_bytes_ = min_foreground_concurrent_start_bytes_;
+ }
}
void Heap::UpdateProcessState(ProcessState old_process_state, ProcessState new_process_state) {
@@ -3730,7 +3733,9 @@
// process-state switch.
min_foreground_target_footprint_ =
(multiplier <= 1.0 && grow_bytes > 0)
- ? bytes_allocated + static_cast<size_t>(grow_bytes * foreground_heap_growth_multiplier_)
+ ? std::min(
+ bytes_allocated + static_cast<size_t>(grow_bytes * foreground_heap_growth_multiplier_),
+ GetMaxMemory())
: 0;
if (IsGcConcurrent()) {
@@ -3762,6 +3767,12 @@
// allocation rate is very high, remaining_bytes could tell us that we should start a GC
// right away.
concurrent_start_bytes_ = std::max(target_footprint - remaining_bytes, bytes_allocated);
+ // Store concurrent_start_bytes_ (computed with foreground heap growth multiplier) for update
+ // itself when process state switches to foreground.
+ min_foreground_concurrent_start_bytes_ =
+ min_foreground_target_footprint_ != 0
+ ? std::max(min_foreground_target_footprint_ - remaining_bytes, bytes_allocated)
+ : 0;
}
}
}
diff --git a/runtime/gc/heap.h b/runtime/gc/heap.h
index 044999d..f03ac34 100644
--- a/runtime/gc/heap.h
+++ b/runtime/gc/heap.h
@@ -1445,8 +1445,9 @@
// Computed with foreground-multiplier in GrowForUtilization() when run in
// jank non-perceptible state. On update to process state from background to
- // foreground we set target_footprint_ to this value.
+ // foreground we set target_footprint_ and concurrent_start_bytes_ to the corresponding value.
size_t min_foreground_target_footprint_ GUARDED_BY(process_state_update_lock_);
+ size_t min_foreground_concurrent_start_bytes_ GUARDED_BY(process_state_update_lock_);
// When num_bytes_allocated_ exceeds this amount then a concurrent GC should be requested so that
// it completes ahead of an allocation failing.