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

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

Issue 7671033: Changing OOM range to 0, 1000 and tweaking OOM algorithm. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: More review changes Created 9 years, 4 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 | Annotate | Revision Log
« no previous file with comments | « chrome/browser/oom_priority_manager.h ('k') | chrome/browser/ui/browser_list.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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/oom_priority_manager.h" 5 #include "chrome/browser/oom_priority_manager.h"
6 6
7 #include <list> 7 #include <list>
8 8
9 #include "base/process.h" 9 #include "base/process.h"
10 #include "base/process_util.h" 10 #include "base/process_util.h"
11 #include "base/threading/thread.h" 11 #include "base/threading/thread.h"
12 #include "build/build_config.h" 12 #include "build/build_config.h"
13 #include "chrome/browser/tabs/tab_strip_model.h" 13 #include "chrome/browser/tabs/tab_strip_model.h"
14 #include "chrome/browser/ui/browser_list.h" 14 #include "chrome/browser/ui/browser_list.h"
15 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" 15 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
16 #include "chrome/common/chrome_constants.h"
16 #include "content/browser/browser_thread.h" 17 #include "content/browser/browser_thread.h"
17 #include "content/browser/renderer_host/render_process_host.h" 18 #include "content/browser/renderer_host/render_process_host.h"
18 #include "content/browser/tab_contents/tab_contents.h" 19 #include "content/browser/tab_contents/tab_contents.h"
19 #include "content/browser/zygote_host_linux.h" 20 #include "content/browser/zygote_host_linux.h"
20 21
21 #if !defined(OS_CHROMEOS) 22 #if !defined(OS_CHROMEOS)
22 #error This file only meant to be compiled on ChromeOS 23 #error This file only meant to be compiled on ChromeOS
23 #endif 24 #endif
24 25
25 using base::TimeDelta; 26 using base::TimeDelta;
26 using base::TimeTicks; 27 using base::TimeTicks;
27 using base::ProcessHandle; 28 using base::ProcessHandle;
28 using base::ProcessMetrics; 29 using base::ProcessMetrics;
29 30
30 namespace browser { 31 namespace browser {
31 32
32 // The default interval in seconds after which to adjust the oom_adj 33 // The default interval in seconds after which to adjust the oom_score_adj
33 // value. 34 // value.
34 #define ADJUSTMENT_INTERVAL_SECONDS 10 35 #define ADJUSTMENT_INTERVAL_SECONDS 10
35 36
36 // The default interval in minutes for considering activation times 37 // The default interval in minutes for considering activation times
37 // "equal". 38 // "equal".
38 #define BUCKET_INTERVAL_MINUTES 10 39 #define BUCKET_INTERVAL_MINUTES 10
39 40
40 OomPriorityManager::OomPriorityManager() { 41 OomPriorityManager::OomPriorityManager() {
41 StartTimer(); 42 StartTimer();
42 } 43 }
(...skipping 16 matching lines...) Expand all
59 60
60 // Returns true if |first| is considered less desirable to be killed 61 // Returns true if |first| is considered less desirable to be killed
61 // than |second|. 62 // than |second|.
62 bool OomPriorityManager::CompareRendererStats(RendererStats first, 63 bool OomPriorityManager::CompareRendererStats(RendererStats first,
63 RendererStats second) { 64 RendererStats second) {
64 // The size of the slop in comparing activation times. [This is 65 // The size of the slop in comparing activation times. [This is
65 // allocated here to avoid static initialization at startup time.] 66 // allocated here to avoid static initialization at startup time.]
66 static const int64 kTimeBucketInterval = 67 static const int64 kTimeBucketInterval =
67 TimeDelta::FromMinutes(BUCKET_INTERVAL_MINUTES).ToInternalValue(); 68 TimeDelta::FromMinutes(BUCKET_INTERVAL_MINUTES).ToInternalValue();
68 69
69 // Being pinned is most important. 70 // Being currently selected is most important.
71 if (first.is_selected != second.is_selected)
72 return first.is_selected == true;
73
74 // Being pinned is second most important.
70 if (first.is_pinned != second.is_pinned) 75 if (first.is_pinned != second.is_pinned)
71 return first.is_pinned == true; 76 return first.is_pinned == true;
72 77
73 // We want to be a little "fuzzy" when we compare these, because 78 // We want to be a little "fuzzy" when we compare these, because
74 // it's not really possible for the times to be identical, but if 79 // it's not really possible for the times to be identical, but if
75 // the user selected two tabs at about the same time, we still want 80 // the user selected two tabs at about the same time, we still want
76 // to take the one that uses more memory. 81 // to take the one that uses more memory.
77 if (abs((first.last_selected - second.last_selected).ToInternalValue()) < 82 if (abs((first.last_selected - second.last_selected).ToInternalValue()) <
78 kTimeBucketInterval) 83 kTimeBucketInterval)
79 return first.last_selected < second.last_selected; 84 return first.last_selected < second.last_selected;
80 85
81 return first.memory_used < second.memory_used; 86 return first.memory_used < second.memory_used;
82 } 87 }
83 88
84 // Here we collect most of the information we need to sort the 89 // Here we collect most of the information we need to sort the
85 // existing renderers in priority order, and hand out oom_adj scores 90 // existing renderers in priority order, and hand out oom_score_adj
86 // based on that sort order. 91 // scores based on that sort order.
87 // 92 //
88 // Things we need to collect on the browser thread (because 93 // Things we need to collect on the browser thread (because
89 // TabStripModel isn't thread safe): 94 // TabStripModel isn't thread safe):
90 // 1) whether or not a tab is pinned 95 // 1) whether or not a tab is pinned
91 // 2) last time a tab was selected 96 // 2) last time a tab was selected
97 // 3) is the tab currently selected
92 // 98 //
93 // We also need to collect: 99 // We also need to collect:
94 // 3) size in memory of a tab 100 // 4) size in memory of a tab
95 // But we do that in DoAdjustOomPriorities on the FILE thread so that 101 // But we do that in DoAdjustOomPriorities on the FILE thread so that
96 // we avoid jank, because it accesses /proc. 102 // we avoid jank, because it accesses /proc.
97 void OomPriorityManager::AdjustOomPriorities() { 103 void OomPriorityManager::AdjustOomPriorities() {
98 if (BrowserList::size() == 0) 104 if (BrowserList::size() == 0)
99 return; 105 return;
100 106
101 StatsList renderer_stats; 107 StatsList renderer_stats;
102 for (BrowserList::const_iterator browser_iterator = BrowserList::begin(); 108 for (BrowserList::const_iterator browser_iterator = BrowserList::begin();
103 browser_iterator != BrowserList::end(); ++browser_iterator) { 109 browser_iterator != BrowserList::end(); ++browser_iterator) {
104 Browser* browser = *browser_iterator; 110 Browser* browser = *browser_iterator;
105 const TabStripModel* model = browser->tabstrip_model(); 111 const TabStripModel* model = browser->tabstrip_model();
106 for (int i = 0; i < model->count(); i++) { 112 for (int i = 0; i < model->count(); i++) {
107 TabContents* contents = model->GetTabContentsAt(i)->tab_contents(); 113 TabContents* contents = model->GetTabContentsAt(i)->tab_contents();
108 RendererStats stats; 114 RendererStats stats;
109 stats.last_selected = contents->last_selected_time(); 115 stats.last_selected = contents->last_selected_time();
110 stats.renderer_handle = contents->GetRenderProcessHost()->GetHandle(); 116 stats.renderer_handle = contents->GetRenderProcessHost()->GetHandle();
111 stats.is_pinned = model->IsTabPinned(i); 117 stats.is_pinned = model->IsTabPinned(i);
112 stats.memory_used = 0; // This gets calculated in DoAdjustOomPriorities. 118 stats.memory_used = 0; // This gets calculated in DoAdjustOomPriorities.
119 stats.is_selected = model->IsTabSelected(i);
113 renderer_stats.push_back(stats); 120 renderer_stats.push_back(stats);
114 } 121 }
115 } 122 }
116 123
117 BrowserThread::PostTask( 124 BrowserThread::PostTask(
118 BrowserThread::FILE, FROM_HERE, 125 BrowserThread::FILE, FROM_HERE,
119 NewRunnableMethod(this, &OomPriorityManager::DoAdjustOomPriorities, 126 NewRunnableMethod(this, &OomPriorityManager::DoAdjustOomPriorities,
120 renderer_stats)); 127 renderer_stats));
121 } 128 }
122 129
(...skipping 15 matching lines...) Expand all
138 // process is gone anyhow. 145 // process is gone anyhow.
139 stats_iter->memory_used = metrics->GetWorkingSetSize(); 146 stats_iter->memory_used = metrics->GetWorkingSetSize();
140 } 147 }
141 } 148 }
142 149
143 // Now we sort the data we collected so that least desirable to be 150 // Now we sort the data we collected so that least desirable to be
144 // killed is first, most desirable is last. 151 // killed is first, most desirable is last.
145 renderer_stats.sort(OomPriorityManager::CompareRendererStats); 152 renderer_stats.sort(OomPriorityManager::CompareRendererStats);
146 153
147 // Now we assign priorities based on the sorted list. We're 154 // Now we assign priorities based on the sorted list. We're
148 // assigning priorities in the range of 5 to 10. oom_adj takes 155 // assigning priorities in the range of kLowestRendererOomScore to
149 // values from -17 to 15. Negative values are reserved for system 156 // kHighestRendererOomScore (defined in chrome_constants.h).
150 // processes, and we want to give some room on either side of the 157 // oom_score_adj takes values from -1000 to 1000. Negative values
151 // range we're using to allow for things that want to be above or 158 // are reserved for system processes, and we want to give some room
152 // below the renderers in priority, so 5 to 10 gives us some 159 // below the range we're using to allow for things that want to be
153 // variation in priority without taking up the whole range. In the 160 // above the renderers in priority, so the defined range gives us
154 // end, however, it's a pretty arbitrary range to use. Higher 161 // some variation in priority without taking up the whole range. In
155 // values are more likely to be killed by the OOM killer. We also 162 // the end, however, it's a pretty arbitrary range to use. Higher
156 // remove any duplicate PIDs, leaving the most important of the 163 // values are more likely to be killed by the OOM killer.
157 // duplicates. 164 //
158 const int kMinPriority = 5; 165 // We also remove any duplicate PIDs, leaving the most important
159 const int kMaxPriority = 10; 166 // (least likely to be killed) of the duplicates, so that a
160 const int kPriorityRange = kMaxPriority - kMinPriority; 167 // particular renderer process takes on the oom_score_adj of the
168 // least likely tab to be killed.
169 const int kPriorityRange = chrome::kHighestRendererOomScore -
170 chrome::kLowestRendererOomScore;
161 float priority_increment = 171 float priority_increment =
162 static_cast<float>(kPriorityRange) / renderer_stats.size(); 172 static_cast<float>(kPriorityRange) / renderer_stats.size();
163 float priority = kMinPriority; 173 float priority = chrome::kLowestRendererOomScore;
164 std::set<base::ProcessHandle> already_seen; 174 std::set<base::ProcessHandle> already_seen;
165 for (StatsList::iterator iterator = renderer_stats.begin(); 175 for (StatsList::iterator iterator = renderer_stats.begin();
166 iterator != renderer_stats.end(); ++iterator) { 176 iterator != renderer_stats.end(); ++iterator) {
167 if (already_seen.find(iterator->renderer_handle) == already_seen.end()) { 177 if (already_seen.find(iterator->renderer_handle) == already_seen.end()) {
168 already_seen.insert(iterator->renderer_handle); 178 already_seen.insert(iterator->renderer_handle);
169 ZygoteHost::GetInstance()->AdjustRendererOOMScore( 179 ZygoteHost::GetInstance()->AdjustRendererOOMScore(
170 iterator->renderer_handle, 180 iterator->renderer_handle, static_cast<int>(priority + 0.5f));
171 static_cast<int>(priority + 0.5f));
172 priority += priority_increment; 181 priority += priority_increment;
173 } 182 }
174 } 183 }
175 } 184 }
176 185
177 } // namespace browser 186 } // namespace browser
OLDNEW
« no previous file with comments | « chrome/browser/oom_priority_manager.h ('k') | chrome/browser/ui/browser_list.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698