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

Side by Side Diff: chrome/browser/memory/oom_priority_manager.cc

Issue 1332003002: Add option to disallow the discarding of a tab that was previously discarded. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: sky@ comments + fix tests. Created 5 years, 3 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
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium 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 "chrome/browser/memory/oom_priority_manager.h" 5 #include "chrome/browser/memory/oom_priority_manager.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <set> 8 #include <set>
9 #include <vector> 9 #include <vector>
10 10
(...skipping 14 matching lines...) Expand all
25 #include "base/threading/thread.h" 25 #include "base/threading/thread.h"
26 #include "build/build_config.h" 26 #include "build/build_config.h"
27 #include "chrome/browser/browser_process.h" 27 #include "chrome/browser/browser_process.h"
28 #include "chrome/browser/memory/oom_memory_details.h" 28 #include "chrome/browser/memory/oom_memory_details.h"
29 #include "chrome/browser/memory/system_memory_stats_recorder.h" 29 #include "chrome/browser/memory/system_memory_stats_recorder.h"
30 #include "chrome/browser/ui/browser.h" 30 #include "chrome/browser/ui/browser.h"
31 #include "chrome/browser/ui/browser_iterator.h" 31 #include "chrome/browser/ui/browser_iterator.h"
32 #include "chrome/browser/ui/browser_list.h" 32 #include "chrome/browser/ui/browser_list.h"
33 #include "chrome/browser/ui/host_desktop.h" 33 #include "chrome/browser/ui/host_desktop.h"
34 #include "chrome/browser/ui/tab_contents/tab_contents_iterator.h" 34 #include "chrome/browser/ui/tab_contents/tab_contents_iterator.h"
35 #include "chrome/browser/ui/tabs/tab_discard_state.h"
35 #include "chrome/browser/ui/tabs/tab_strip_model.h" 36 #include "chrome/browser/ui/tabs/tab_strip_model.h"
36 #include "chrome/browser/ui/tabs/tab_utils.h" 37 #include "chrome/browser/ui/tabs/tab_utils.h"
37 #include "chrome/common/chrome_constants.h" 38 #include "chrome/common/chrome_constants.h"
38 #include "chrome/common/url_constants.h" 39 #include "chrome/common/url_constants.h"
39 #include "content/public/browser/browser_thread.h" 40 #include "content/public/browser/browser_thread.h"
40 #include "content/public/browser/render_process_host.h" 41 #include "content/public/browser/render_process_host.h"
41 #include "content/public/browser/web_contents.h" 42 #include "content/public/browser/web_contents.h"
42 43
43 #if defined(OS_CHROMEOS) 44 #if defined(OS_CHROMEOS)
44 #include "chrome/browser/memory/oom_priority_manager_delegate_chromeos.h" 45 #include "chrome/browser/memory/oom_priority_manager_delegate_chromeos.h"
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
88 89
89 return -1; 90 return -1;
90 } 91 }
91 92
92 } // namespace 93 } // namespace
93 94
94 //////////////////////////////////////////////////////////////////////////////// 95 ////////////////////////////////////////////////////////////////////////////////
95 // OomPriorityManager 96 // OomPriorityManager
96 97
97 OomPriorityManager::OomPriorityManager() 98 OomPriorityManager::OomPriorityManager()
98 : discard_count_(0), recent_tab_discard_(false) { 99 : discard_count_(0), recent_tab_discard_(false), discard_once_(false) {
99 #if defined(OS_CHROMEOS) 100 #if defined(OS_CHROMEOS)
100 delegate_.reset(new OomPriorityManagerDelegate); 101 delegate_.reset(new OomPriorityManagerDelegate);
101 #endif 102 #endif
102 } 103 }
103 104
104 OomPriorityManager::~OomPriorityManager() { 105 OomPriorityManager::~OomPriorityManager() {
105 Stop(); 106 Stop();
106 } 107 }
107 108
108 void OomPriorityManager::Start() { 109 void OomPriorityManager::Start(bool discard_once) {
110 discard_once_ = discard_once;
109 if (!update_timer_.IsRunning()) { 111 if (!update_timer_.IsRunning()) {
110 update_timer_.Start(FROM_HERE, 112 update_timer_.Start(FROM_HERE,
111 TimeDelta::FromSeconds(kAdjustmentIntervalSeconds), 113 TimeDelta::FromSeconds(kAdjustmentIntervalSeconds),
112 this, &OomPriorityManager::UpdateTimerCallback); 114 this, &OomPriorityManager::UpdateTimerCallback);
113 } 115 }
114 if (!recent_tab_discard_timer_.IsRunning()) { 116 if (!recent_tab_discard_timer_.IsRunning()) {
115 recent_tab_discard_timer_.Start( 117 recent_tab_discard_timer_.Start(
116 FROM_HERE, TimeDelta::FromSeconds(kRecentTabDiscardIntervalSeconds), 118 FROM_HERE, TimeDelta::FromSeconds(kRecentTabDiscardIntervalSeconds),
117 this, &OomPriorityManager::RecordRecentTabDiscard); 119 this, &OomPriorityManager::RecordRecentTabDiscard);
118 } 120 }
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
171 // discard the entire set together, or use that in the priority computation. 173 // discard the entire set together, or use that in the priority computation.
172 bool OomPriorityManager::DiscardTab() { 174 bool OomPriorityManager::DiscardTab() {
173 DCHECK_CURRENTLY_ON(BrowserThread::UI); 175 DCHECK_CURRENTLY_ON(BrowserThread::UI);
174 TabStatsList stats = GetTabStats(); 176 TabStatsList stats = GetTabStats();
175 if (stats.empty()) 177 if (stats.empty())
176 return false; 178 return false;
177 // Loop until we find a non-discarded tab to kill. 179 // Loop until we find a non-discarded tab to kill.
178 for (TabStatsList::const_reverse_iterator stats_rit = stats.rbegin(); 180 for (TabStatsList::const_reverse_iterator stats_rit = stats.rbegin();
179 stats_rit != stats.rend(); ++stats_rit) { 181 stats_rit != stats.rend(); ++stats_rit) {
180 int64 least_important_tab_id = stats_rit->tab_contents_id; 182 int64 least_important_tab_id = stats_rit->tab_contents_id;
181 if (DiscardTabById(least_important_tab_id)) 183 if (CanDiscardTab(least_important_tab_id) &&
184 DiscardTabById(least_important_tab_id))
182 return true; 185 return true;
183 } 186 }
184 return false; 187 return false;
185 } 188 }
186 189
187 bool OomPriorityManager::DiscardTabById(int64 target_web_contents_id) { 190 bool OomPriorityManager::DiscardTabById(int64 target_web_contents_id) {
188 TabStripModel* model; 191 TabStripModel* model;
189 int idx = FindTabStripModelById(target_web_contents_id, &model); 192 int idx = FindTabStripModelById(target_web_contents_id, &model);
190 193
191 if (idx == -1) 194 if (idx == -1)
192 return false; 195 return false;
193 196
194 // Can't discard tabs that are already discarded or active. 197 // Can't discard active tabs
195 if (model->IsTabDiscarded(idx) || (model->active_index() == idx)) 198 if (model->active_index() == idx)
196 return false; 199 return false;
197 200
198 // We also ignore tabs that are playing audio as it's too distruptive to 201 WebContents* web_contents = model->GetWebContentsAt(idx);
199 // the user experience. 202 // Can't discard tabs that are already discarded.
200 if (model->GetWebContentsAt(idx)->WasRecentlyAudible()) 203 if (TabDiscardState::IsDiscarded(web_contents))
201 return false; 204 return false;
202 205
203 VLOG(1) << "Discarding tab " << idx << " id " << target_web_contents_id; 206 VLOG(1) << "Discarding tab " << idx << " id " << target_web_contents_id;
204 // Record statistics before discarding because we want to capture the 207 // Record statistics before discarding because we want to capture the
205 // memory state that lead to the discard. 208 // memory state that lead to the discard.
206 RecordDiscardStatistics(); 209 RecordDiscardStatistics();
207 model->DiscardWebContentsAt(idx); 210 model->DiscardWebContentsAt(idx);
208 recent_tab_discard_ = true; 211 recent_tab_discard_ = true;
209 212
210 return true; 213 return true;
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
418 for (int i = 0; i < model->count(); i++) { 421 for (int i = 0; i < model->count(); i++) {
419 WebContents* contents = model->GetWebContentsAt(i); 422 WebContents* contents = model->GetWebContentsAt(i);
420 if (!contents->IsCrashed()) { 423 if (!contents->IsCrashed()) {
421 TabStats stats; 424 TabStats stats;
422 stats.is_app = is_browser_for_app; 425 stats.is_app = is_browser_for_app;
423 stats.is_internal_page = 426 stats.is_internal_page =
424 IsInternalPage(contents->GetLastCommittedURL()); 427 IsInternalPage(contents->GetLastCommittedURL());
425 stats.is_playing_audio = contents->WasRecentlyAudible(); 428 stats.is_playing_audio = contents->WasRecentlyAudible();
426 stats.is_pinned = model->IsTabPinned(i); 429 stats.is_pinned = model->IsTabPinned(i);
427 stats.is_selected = browser_active && model->IsTabSelected(i); 430 stats.is_selected = browser_active && model->IsTabSelected(i);
428 stats.is_discarded = model->IsTabDiscarded(i); 431 stats.is_discarded = TabDiscardState::IsDiscarded(contents);
432 stats.discard_count = TabDiscardState::DiscardCount(contents);
429 stats.last_active = contents->GetLastActiveTime(); 433 stats.last_active = contents->GetLastActiveTime();
430 stats.renderer_handle = contents->GetRenderProcessHost()->GetHandle(); 434 stats.renderer_handle = contents->GetRenderProcessHost()->GetHandle();
431 stats.child_process_host_id = contents->GetRenderProcessHost()->GetID(); 435 stats.child_process_host_id = contents->GetRenderProcessHost()->GetID();
432 #if defined(OS_CHROMEOS) 436 #if defined(OS_CHROMEOS)
433 stats.oom_score = delegate_->GetOomScore(stats.child_process_host_id); 437 stats.oom_score = delegate_->GetOomScore(stats.child_process_host_id);
434 #endif 438 #endif
435 stats.title = contents->GetTitle(); 439 stats.title = contents->GetTitle();
436 stats.tab_contents_id = IdFromWebContents(contents); 440 stats.tab_contents_id = IdFromWebContents(contents);
437 stats_list->push_back(stats); 441 stats_list->push_back(stats);
438 } 442 }
(...skipping 11 matching lines...) Expand all
450 454
451 // For the moment we only do something when we reach a critical state. 455 // For the moment we only do something when we reach a critical state.
452 if (memory_pressure_level == 456 if (memory_pressure_level ==
453 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL) { 457 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL) {
454 LogMemoryAndDiscardTab(); 458 LogMemoryAndDiscardTab();
455 } 459 }
456 // TODO(skuhne): If more memory pressure levels are introduced, we might 460 // TODO(skuhne): If more memory pressure levels are introduced, we might
457 // consider to call PurgeBrowserMemory() before CRITICAL is reached. 461 // consider to call PurgeBrowserMemory() before CRITICAL is reached.
458 } 462 }
459 463
464 bool OomPriorityManager::CanDiscardTab(int64 target_web_contents_id) const {
465 TabStripModel* model;
466 int idx = FindTabStripModelById(target_web_contents_id, &model);
467
468 if (idx == -1)
469 return false;
470
471 WebContents* web_contents = model->GetWebContentsAt(idx);
472 // We do not discard tabs that are playing audio as it's too distruptive to
473 // the user experience.
474 if (web_contents->WasRecentlyAudible())
475 return false;
476
477 // We also make sure not to discard a previously discarded tab if that's the
478 // desired behavior.
479 if (discard_once_ && TabDiscardState::DiscardCount(web_contents) > 0)
480 return false;
481
482 return true;
483 }
484
460 } // namespace memory 485 } // namespace memory
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698