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

Unified Diff: chrome/browser/memory/tab_manager.cc

Issue 2711093002: Purge once random minutes(between 30min and 60min) after backgrounded. (Closed)
Patch Set: s/RUNNING/NOT_PURGED/g Created 3 years, 10 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/memory/tab_manager.cc
diff --git a/chrome/browser/memory/tab_manager.cc b/chrome/browser/memory/tab_manager.cc
index 959ebdcdaefb72159122a6bb1babe1247113d23f..31d95b3b151ab12dc1f16261477b7d7308618ace 100644
--- a/chrome/browser/memory/tab_manager.cc
+++ b/chrome/browser/memory/tab_manager.cc
@@ -20,6 +20,7 @@
#include "base/metrics/histogram_macros.h"
#include "base/observer_list.h"
#include "base/process/process.h"
+#include "base/rand_util.h"
#include "base/strings/string16.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
@@ -84,13 +85,10 @@ const int kRecentTabDiscardIntervalSeconds = 60;
// machine was suspended and correct the timing statistics.
const int kSuspendThresholdSeconds = kAdjustmentIntervalSeconds * 4;
-// A suspended renderer is suspended for this duration.
-constexpr base::TimeDelta kDurationOfRendererSuspension =
- base::TimeDelta::FromSeconds(1200);
-
-// A resumed renderer is resumed for this duration.
-constexpr base::TimeDelta kDurationOfRendererResumption =
- base::TimeDelta::FromSeconds(10);
+// Within the following range after the tab is backgrounded and
+// time_to_first_purge_ passes, purge the tab's cache if the tab is still
+// backgrounded and in-active.
Wez 2017/02/27 22:20:55 This comment is pretty confusingly worded! Would
tasak 2017/02/28 09:45:37 Done.
+const unsigned int kRangeOfTimeToFirstPurgeInMinutes = 30;
chrisha 2017/02/27 13:31:06 How is this a range? Or is it implicitly lower bou
tasak 2017/02/28 09:45:37 Done.
// The time during which a tab is protected from discarding after it stops being
// audible.
@@ -231,9 +229,9 @@ void TabManager::Start() {
unsigned int time_to_first_purge_sec = 0;
if (purge_and_suspend_time.empty() ||
!base::StringToUint(purge_and_suspend_time, &time_to_first_purge_sec))
- time_to_first_suspension_ = kDefaultTimeToFirstPurge;
+ time_to_first_purge_ = kDefaultTimeToFirstPurge;
else
- time_to_first_suspension_ =
+ time_to_first_purge_ =
base::TimeDelta::FromSeconds(time_to_first_purge_sec);
}
@@ -716,37 +714,26 @@ void TabManager::UpdateTimerCallback() {
delegate_->AdjustOomPriorities(stats_list);
#endif
- PurgeAndSuspendBackgroundedTabs();
+ PurgeBackgroundedTabs();
}
-TabManager::PurgeAndSuspendState TabManager::GetNextPurgeAndSuspendState(
+TabManager::PurgeState TabManager::GetNextPurgeState(
content::WebContents* content,
- base::TimeTicks current_time,
- const base::TimeDelta& time_to_first_suspension) const {
+ base::TimeTicks current_time) const {
DCHECK(content);
Wez 2017/02/27 22:20:55 You don't need a DCHECK here, since you're about t
tasak 2017/02/28 09:45:37 Done.
- PurgeAndSuspendState state =
- GetWebContentsData(content)->GetPurgeAndSuspendState();
-
- auto time_passed = current_time -
- GetWebContentsData(content)->LastPurgeAndSuspendModifiedTime();
- switch (state) {
- case RUNNING:
- if (time_passed > time_to_first_suspension)
- return SUSPENDED;
- break;
- case RESUMED:
- if (time_passed > kDurationOfRendererResumption)
- return SUSPENDED;
- break;
- case SUSPENDED:
- if (time_passed > kDurationOfRendererSuspension)
- return RESUMED;
- break;
- }
+ PurgeState state = GetWebContentsData(content)->GetPurgeState();
+ if (state == PURGED)
+ return state;
+
+ DCHECK(state == NOT_PURGED);
Wez 2017/02/27 22:20:55 This is a tautologous DCHECK, since there are only
tasak 2017/02/28 09:45:37 Done.
+ auto time_passed =
Wez 2017/02/27 22:20:55 There's no need to use |auto| here; it makes the c
tasak 2017/02/28 09:45:37 Done.
+ current_time - GetWebContentsData(content)->LastInactiveTime();
+ if (time_passed > GetWebContentsData(content)->TimeToFirstPurge())
+ return PURGED;
return state;
}
-void TabManager::PurgeAndSuspendBackgroundedTabs() {
+void TabManager::PurgeBackgroundedTabs() {
base::TimeTicks current_time = NowTicks();
auto tab_stats = GetUnsortedTabStats();
for (auto& tab : tab_stats) {
@@ -759,16 +746,8 @@ void TabManager::PurgeAndSuspendBackgroundedTabs() {
if (!content)
continue;
- PurgeAndSuspendState current_state =
- GetWebContentsData(content)->GetPurgeAndSuspendState();
- // If the tab's purge-and-suspend state is not RUNNING, the tab should be
- // backgrounded. Since tab.last_hidden is updated everytime the tab is
- // hidden, we should see tab.last_hidden < last_modified_time.
- DCHECK(current_state == RUNNING ||
- tab.last_hidden <
- GetWebContentsData(content)->LastPurgeAndSuspendModifiedTime());
- PurgeAndSuspendState next_state = GetNextPurgeAndSuspendState(
- content, current_time, time_to_first_suspension_);
+ PurgeState current_state = GetWebContentsData(content)->GetPurgeState();
+ PurgeState next_state = GetNextPurgeState(content, current_time);
if (current_state == next_state)
continue;
@@ -776,17 +755,11 @@ void TabManager::PurgeAndSuspendBackgroundedTabs() {
// timers for simplicity, so PurgeAndSuspend is called even after the
// renderer is purged and suspended once. This should be replaced with
// timers if we want necessary and sufficient signals.
Wez 2017/02/27 22:20:55 It's not clear what this (pre-existing) comment is
tasak 2017/02/28 09:45:37 Done.
- GetWebContentsData(content)->SetPurgeAndSuspendState(next_state);
- switch (next_state) {
- case SUSPENDED:
- tab.render_process_host->PurgeAndSuspend();
- break;
- case RESUMED:
- tab.render_process_host->Resume();
- break;
- case RUNNING:
- NOTREACHED();
- }
+ GetWebContentsData(content)->SetPurgeState(next_state);
+ DCHECK(next_state == PURGED);
Wez 2017/02/27 22:20:55 As noted in the previous function, you can replace
tasak 2017/02/28 09:45:37 Done.
+ // TODO(tasak): rename PurgeAndSuspend with a better name, e.g.
+ // RequestPurgeCache, because we don't suspend any renderers.
+ tab.render_process_host->PurgeAndSuspend();
}
}
@@ -887,7 +860,15 @@ void TabManager::ActiveTabChanged(content::WebContents* old_contents,
int index,
int reason) {
GetWebContentsData(new_contents)->SetDiscardState(false);
- GetWebContentsData(new_contents)->SetPurgeAndSuspendState(RUNNING);
+ // To avoid purging many processes' cache at the same time, we will use
+ // time_to_first_purge_ + random value with in the range
+ // kRangeOfTimeToFirstPurgeInMinutes to invoke purge.
Wez 2017/02/27 22:20:55 I think the more important thing to get across in
tasak 2017/02/28 09:45:37 Moved the code into the statement: if(old_contents
+ base::TimeDelta time_to_first_purge =
+ time_to_first_purge_ +
+ base::TimeDelta::FromMinutes(
+ base::RandGenerator(kRangeOfTimeToFirstPurgeInMinutes));
+ GetWebContentsData(new_contents)->SetTimeToFirstPurge(time_to_first_purge);
Wez 2017/02/27 22:20:55 nit: I'd suggest calling this SetTimeToPurge(), so
tasak 2017/02/28 09:45:37 Done.
+ GetWebContentsData(new_contents)->SetPurgeState(NOT_PURGED);
// If |old_contents| is set, that tab has switched from being active to
// inactive, so record the time of that transition.
if (old_contents)

Powered by Google App Engine
This is Rietveld 408576698