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

Unified Diff: content/browser/memory/memory_coordinator_impl.cc

Issue 2479673002: Expose MemoryCoordinator's global budget information. (Closed)
Patch Set: Small cleanup. Created 4 years, 1 month 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
Index: content/browser/memory/memory_coordinator_impl.cc
diff --git a/content/browser/memory/memory_coordinator_impl.cc b/content/browser/memory/memory_coordinator_impl.cc
index 776ce283100a477c4979ead20a61df487522134a..a5255b5edca7562349d4e64e4d636d057b6994d8 100644
--- a/content/browser/memory/memory_coordinator_impl.cc
+++ b/content/browser/memory/memory_coordinator_impl.cc
@@ -76,6 +76,7 @@ MemoryCoordinatorImpl::MemoryCoordinatorImpl(
std::unique_ptr<MemoryMonitor> memory_monitor)
: task_runner_(task_runner),
memory_monitor_(std::move(memory_monitor)),
+ remaining_global_budget_mb_(0),
weak_ptr_factory_(this) {
DCHECK(memory_monitor_.get());
update_state_callback_ = base::Bind(&MemoryCoordinatorImpl::UpdateState,
@@ -132,6 +133,10 @@ void MemoryCoordinatorImpl::SetCurrentMemoryStateForTesting(
}
}
+int64_t MemoryCoordinatorImpl::GetRemainingGlobalBudget() const {
+ return remaining_global_budget_mb_;
+}
+
void MemoryCoordinatorImpl::Observe(int type,
const NotificationSource& source,
const NotificationDetails& details) {
@@ -150,15 +155,18 @@ void MemoryCoordinatorImpl::Observe(int type,
SetMemoryState(iter->first, new_state);
}
-base::MemoryState MemoryCoordinatorImpl::CalculateNextState() {
+base::MemoryState MemoryCoordinatorImpl::CalculateNextState(
+ int free_memory_until_critical_mb) {
using MemoryState = base::MemoryState;
- int available = memory_monitor_->GetFreeMemoryUntilCriticalMB();
- if (available <= 0)
+ // If memory is already critical then immediately go to the most aggressive
+ // state.
+ if (free_memory_until_critical_mb <= 0)
return MemoryState::SUSPENDED;
- int expected_renderer_count = available / expected_renderer_size_;
-
+ // Determine the next state.
+ int expected_renderer_count =
+ free_memory_until_critical_mb / expected_renderer_size_;
switch (current_state_) {
case MemoryState::NORMAL:
if (expected_renderer_count <= new_renderers_until_suspended_)
@@ -179,17 +187,30 @@ base::MemoryState MemoryCoordinatorImpl::CalculateNextState() {
return MemoryState::THROTTLED;
return MemoryState::SUSPENDED;
case MemoryState::UNKNOWN:
- // Fall through
+ // Fall through.
default:
NOTREACHED();
return MemoryState::UNKNOWN;
}
}
+int64_t MemoryCoordinatorImpl::CalculateRemainingGlobalBudget(
+ int free_memory_until_critical_mb) {
+ int renderer_count = new_renderers_until_throttled_;
Hannes Payer (out of office) 2016/11/11 12:55:19 I do not understand why you use kDefaultNewRendere
bashi 2016/11/12 01:30:53 Because we don't know what an appropriate value fo
+ if (current_state_ != MemoryState::NORMAL)
+ renderer_count = new_renderers_back_to_normal_;
haraken 2016/11/05 12:52:21 Shouldn't new_renderers_back_to_normal_ be always
bashi 2016/11/07 00:16:37 We have different parameters for # of renderers to
chrisha 2016/11/07 19:33:41 Yeah, this enables a "dead band" to prevent thrash
+
+ return free_memory_until_critical_mb -
+ renderer_count * expected_renderer_size_;
+}
+
void MemoryCoordinatorImpl::UpdateState() {
base::TimeTicks now = base::TimeTicks::Now();
+
+ int available = memory_monitor_->GetFreeMemoryUntilCriticalMB();
+
MemoryState prev_state = current_state_;
- MemoryState next_state = CalculateNextState();
+ MemoryState next_state = CalculateNextState(available);
if (last_state_change_.is_null() || current_state_ != next_state) {
current_state_ = next_state;
@@ -207,6 +228,16 @@ void MemoryCoordinatorImpl::UpdateState() {
} else {
ScheduleUpdateState(monitoring_interval_);
}
+
+ // Update the global budget. This is used by some passive clients of the
+ // memory coordinator to smoothly scale their own resource consumption in
+ // sync with the memory coordinator.
+ int64_t prev_remaining = remaining_global_budget_mb_;
+ int64_t next_remaining = CalculateRemainingGlobalBudget(available);
+ if (prev_remaining != next_remaining) {
bashi 2016/11/07 00:16:37 How likely does this condition become true? |free_
chrisha 2016/11/07 19:33:41 Very unlikely to remain true, but this is a cheap
bashi 2016/11/07 23:17:08 Acknowledged.
chrisha 2016/12/15 21:10:24 (This is a moot point with a "pull" model.)
+ remaining_global_budget_mb_ = next_remaining;
+ NotifyRemainingGlobalBudgetToChildren();
haraken 2016/11/05 12:52:21 How frequently will this IPC be called?
bashi 2016/11/07 00:16:37 My guess is that it's almost the same as how frequ
chrisha 2016/11/07 19:33:41 Yup. Although we should likely still continue to c
bashi 2016/11/07 23:17:08 Yeah, as haraken@ said, async API may not be usefu
Hannes Payer (out of office) 2016/11/11 12:55:19 Currently, I am only planning to take advantage of
chrisha 2016/12/15 21:10:24 Moved to a "pull" model.
+ }
}
void MemoryCoordinatorImpl::NotifyStateToClients() {
@@ -222,6 +253,11 @@ void MemoryCoordinatorImpl::NotifyStateToChildren() {
SetMemoryState(iter.first, mojo_state);
}
+void MemoryCoordinatorImpl::NotifyRemainingGlobalBudgetToChildren() {
+ for (auto& iter : children())
+ SetRemainingGlobalBudget(iter.first, remaining_global_budget_mb_);
+}
+
void MemoryCoordinatorImpl::ScheduleUpdateState(base::TimeDelta delta) {
task_runner_->PostDelayedTask(FROM_HERE, update_state_callback_, delta);
}

Powered by Google App Engine
This is Rietveld 408576698