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

Side by Side Diff: chrome/browser/memory/tab_manager_delegate_chromeos.h

Issue 2095413002: TabManagerDelegate: Better prioritize ARC processes. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: minor fixes Created 4 years, 5 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 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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 #ifndef CHROME_BROWSER_MEMORY_TAB_MANAGER_DELEGATE_CHROMEOS_H_ 5 #ifndef CHROME_BROWSER_MEMORY_TAB_MANAGER_DELEGATE_CHROMEOS_H_
6 #define CHROME_BROWSER_MEMORY_TAB_MANAGER_DELEGATE_CHROMEOS_H_ 6 #define CHROME_BROWSER_MEMORY_TAB_MANAGER_DELEGATE_CHROMEOS_H_
7 7
8 #include <memory> 8 #include <memory>
9 #include <utility> 9 #include <utility>
10 #include <vector> 10 #include <vector>
11 11
12 #include "base/containers/hash_tables.h" 12 #include "base/containers/hash_tables.h"
13 #include "base/gtest_prod_util.h" 13 #include "base/gtest_prod_util.h"
14 #include "base/logging.h"
14 #include "base/macros.h" 15 #include "base/macros.h"
15 #include "base/memory/weak_ptr.h" 16 #include "base/memory/weak_ptr.h"
16 #include "base/process/process.h" 17 #include "base/process/process.h"
17 #include "base/timer/timer.h" 18 #include "base/timer/timer.h"
18 #include "chrome/browser/chromeos/arc/arc_process.h" 19 #include "chrome/browser/chromeos/arc/arc_process.h"
19 #include "chrome/browser/memory/tab_manager.h" 20 #include "chrome/browser/memory/tab_manager.h"
20 #include "chrome/browser/memory/tab_stats.h" 21 #include "chrome/browser/memory/tab_stats.h"
21 #include "chrome/browser/ui/browser_list_observer.h" 22 #include "chrome/browser/ui/browser_list_observer.h"
22 #include "components/arc/arc_bridge_service.h" 23 #include "components/arc/arc_bridge_service.h"
24 #include "components/arc/common/process.mojom.h"
23 #include "components/arc/instance_holder.h" 25 #include "components/arc/instance_holder.h"
24 #include "content/public/browser/notification_observer.h" 26 #include "content/public/browser/notification_observer.h"
25 #include "content/public/browser/notification_registrar.h" 27 #include "content/public/browser/notification_registrar.h"
26 #include "ui/wm/public/activation_change_observer.h" 28 #include "ui/wm/public/activation_change_observer.h"
27 29
28 namespace memory { 30 namespace memory {
29 31
30 // The importance of tabs/apps. The lower the value, the more likely a process 32 // Possible types of Apps/Tabs processes. From most important to least
31 // is to be selected on memory pressure. The values is additive, for example, 33 // important.
32 // one tab could be of value (CHROME_NORMAL | CHROME_PINNED). 34 enum ProcessType {
Yusuke Sato 2016/07/15 00:55:05 enum class ?
cylee1 2016/07/15 17:31:13 Yes I can make it so, at the expense of overloadin
Luis Héctor Chávez 2016/07/15 18:10:06 I think it's fine to overload operator<<. You are
cylee1 2016/07/20 17:57:53 ok agree.
33 // TODO(cylee): Refactor this CL so the prioritize logic is unified in 35 // There can be only one process having process type "FOCUSED_APP"
34 // TabManager. 36 // or "FOCUSED_TAB" in the system at any give time (i.e., The focused window
35 enum ProcessPriority { 37 // could be either a chrome window or an Android app. But not both.
36 // Processes on Android side which generally don't have an app window, and 38 FOCUSED_APP = 1,
37 // possibly be auto relaunched if killed. 39 FOCUSED_TAB = FOCUSED_APP,
38 ANDROID_BACKGROUND = 1,
39 ANDROID_SERVICE = 1 << 1,
40 ANDROID_CANT_SAVE_STATE = 1 << 2,
41 ANDROID_PERCEPTIBLE = 1 << 3,
42 ANDROID_VISIBLE = 1 << 4,
43 ANDROID_TOP_SLEEPING = 1 << 5,
44 ANDROID_FOREGROUND_SERVICE = 1 << 6,
45 ANDROID_FOREGROUND = 1 << 7,
46 // A chrome window can be one of the 3 exclusive types below:
47 // internal page, normal page, or chrome app.
48 CHROME_INTERNAL = 1 << 8,
49 CHROME_NORMAL = 1 << 9,
50 CHROME_APP = 1 << 10,
51 // An android app which is on top of screen from Android's point of view,
52 // but the app window is inactive from Chrome OS's point of view.
53 // Give it a higher priority then normal chrome tab since it could not be
54 // reloaded if killed.
55 ANDROID_TOP_INACTIVE = CHROME_APP,
56 // A chrome tab could have following 3 additional attributes
57 // (not exclusive).
58 CHROME_PINNED = 1 << 11,
59 CHROME_MEDIA = 1 << 12,
60 CHROME_CANT_SAVE_STATE = 1 << 13,
61 // The highest level of priority. Either a selected tab or an Android app in
62 // an active window. In theory there should be at most one process with this
63 // priority at a time, but at the time of writing Chrome couldn't get Android
64 // window stack info yet so there may be multiple Android apps be token as on
65 // top of screen for now.
66 CHROME_SELECTED = 1 << 14,
67 ANDROID_TOP = CHROME_SELECTED,
68 40
69 ANDROID_PERSISTENT = 1 << 30, 41 VISIBLE_APP = 2,
70 ANDROID_NON_EXISTS = 0x7FFFFFFF 42 BACKGROUND_TAB = 3,
43 BACKGROUND_APP = 4,
44 UNKNOWN_TYPE = 5,
71 }; 45 };
72 46
73 // The Chrome OS TabManagerDelegate is responsible for keeping the 47 // The Chrome OS TabManagerDelegate is responsible for keeping the
74 // renderers' scores up to date in /proc/<pid>/oom_score_adj. 48 // renderers' scores up to date in /proc/<pid>/oom_score_adj.
75 // 49 //
76 // Note that AdjustOomPriorities will be called on the UI thread by 50 // Note that AdjustOomPriorities will be called on the UI thread by
77 // TabManager, but the actual work will take place on the file thread 51 // TabManager, but the actual work will take place on the file thread
78 // (see implementation of AdjustOomPriorities). 52 // (see implementation of AdjustOomPriorities).
79 class TabManagerDelegate 53 class TabManagerDelegate
80 : public arc::InstanceHolder<arc::mojom::ProcessInstance>::Observer, 54 : public arc::InstanceHolder<arc::mojom::ProcessInstance>::Observer,
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
127 101
128 // Kills a tab. Returns true if the tab is killed successfully. 102 // Kills a tab. Returns true if the tab is killed successfully.
129 // Virtual for unit testing. 103 // Virtual for unit testing.
130 virtual bool KillTab(int64_t tab_id); 104 virtual bool KillTab(int64_t tab_id);
131 105
132 private: 106 private:
133 FRIEND_TEST_ALL_PREFIXES(TabManagerDelegateTest, CandidatesSorted); 107 FRIEND_TEST_ALL_PREFIXES(TabManagerDelegateTest, CandidatesSorted);
134 FRIEND_TEST_ALL_PREFIXES(TabManagerDelegateTest, KillMultipleProcesses); 108 FRIEND_TEST_ALL_PREFIXES(TabManagerDelegateTest, KillMultipleProcesses);
135 FRIEND_TEST_ALL_PREFIXES(TabManagerDelegateTest, SetOomScoreAdj); 109 FRIEND_TEST_ALL_PREFIXES(TabManagerDelegateTest, SetOomScoreAdj);
136 110
137 struct Candidate; 111 class Candidate;
138 class FocusedProcess; 112 class FocusedProcess;
139 class UmaReporter; 113 class UmaReporter;
140 114
141 friend std::ostream& operator<<(std::ostream& out, 115 friend std::ostream& operator<<(std::ostream& out,
142 const Candidate& candidate); 116 const Candidate& candidate);
143 117
144 // content::NotificationObserver: 118 // content::NotificationObserver:
145 void Observe(int type, 119 void Observe(int type,
146 const content::NotificationSource& source, 120 const content::NotificationSource& source,
147 const content::NotificationDetails& details) override; 121 const content::NotificationDetails& details) override;
148 122
149 // Pair to hold child process host id and ProcessHandle. 123 // Pair to hold child process host id and ProcessHandle.
150 typedef std::pair<int, base::ProcessHandle> ProcessInfo; 124 typedef std::pair<int, base::ProcessHandle> ProcessInfo;
151 125
152 // Cache OOM scores in memory. 126 // Cache OOM scores in memory.
153 typedef base::hash_map<base::ProcessHandle, int> ProcessScoreMap; 127 typedef base::hash_map<base::ProcessHandle, int> ProcessScoreMap;
154 128
155 // Get the list of candidates to kill, sorted by reversed importance. 129 // Get the list of candidates to kill, sorted by importance descendingly.
Luis Héctor Chávez 2016/07/15 01:29:24 nit: descending importance
cylee1 2016/07/15 17:31:13 Done.
156 static std::vector<Candidate> GetSortedCandidates( 130 static std::vector<Candidate> GetSortedCandidates(
157 const TabStatsList& tab_list, 131 const TabStatsList& tab_list,
158 const std::vector<arc::ArcProcess>& arc_processes); 132 const std::vector<arc::ArcProcess>& arc_processes);
159 133
160 // Posts AdjustFocusedTabScore task to the file thread. 134 // Posts AdjustFocusedTabScore task to the file thread.
161 void OnFocusTabScoreAdjustmentTimeout(); 135 void OnFocusTabScoreAdjustmentTimeout();
162 136
163 // Kills a process after getting all info of tabs and apps. 137 // Kills a process after getting all info of tabs and apps.
164 void LowMemoryKillImpl(const TabStatsList& tab_list, 138 void LowMemoryKillImpl(const TabStatsList& tab_list,
165 const std::vector<arc::ArcProcess>& arc_processes); 139 const std::vector<arc::ArcProcess>& arc_processes);
(...skipping 17 matching lines...) Expand all
183 void SetOomScoreAdjForApp(int nspid, int score); 157 void SetOomScoreAdjForApp(int nspid, int score);
184 158
185 // Sets oom_score_adj for a list of tabs on the file thread. 159 // Sets oom_score_adj for a list of tabs on the file thread.
186 void SetOomScoreAdjForTabsOnFileThread( 160 void SetOomScoreAdjForTabsOnFileThread(
187 const std::vector<std::pair<base::ProcessHandle, int>>& entries); 161 const std::vector<std::pair<base::ProcessHandle, int>>& entries);
188 162
189 // Sets OOM score for processes in the range [|rbegin|, |rend|) to integers 163 // Sets OOM score for processes in the range [|rbegin|, |rend|) to integers
190 // distributed evenly in [|range_begin|, |range_end|). 164 // distributed evenly in [|range_begin|, |range_end|).
191 // The new score is set in |new_map|. 165 // The new score is set in |new_map|.
192 void DistributeOomScoreInRange( 166 void DistributeOomScoreInRange(
193 std::vector<TabManagerDelegate::Candidate>::reverse_iterator rbegin, 167 std::vector<TabManagerDelegate::Candidate>::const_iterator begin,
194 std::vector<TabManagerDelegate::Candidate>::reverse_iterator rend, 168 std::vector<TabManagerDelegate::Candidate>::const_iterator end,
195 int range_begin, 169 int range_begin,
196 int range_end, 170 int range_end,
197 ProcessScoreMap* new_map); 171 ProcessScoreMap* new_map);
198 172
199 // Initiates an oom priority adjustment. 173 // Initiates an oom priority adjustment.
200 void ScheduleEarlyOomPrioritiesAdjustment(); 174 void ScheduleEarlyOomPrioritiesAdjustment();
201 175
202 // Holds a reference to the owning TabManager. 176 // Holds a reference to the owning TabManager.
203 const base::WeakPtr<TabManager> tab_manager_; 177 const base::WeakPtr<TabManager> tab_manager_;
204 178
(...skipping 24 matching lines...) Expand all
229 // Reports UMA histograms. 203 // Reports UMA histograms.
230 std::unique_ptr<UmaReporter> uma_; 204 std::unique_ptr<UmaReporter> uma_;
231 205
232 // Weak pointer factory used for posting tasks to other threads. 206 // Weak pointer factory used for posting tasks to other threads.
233 base::WeakPtrFactory<TabManagerDelegate> weak_ptr_factory_; 207 base::WeakPtrFactory<TabManagerDelegate> weak_ptr_factory_;
234 208
235 DISALLOW_COPY_AND_ASSIGN(TabManagerDelegate); 209 DISALLOW_COPY_AND_ASSIGN(TabManagerDelegate);
236 }; 210 };
237 211
238 // On ARC enabled machines, either a tab or an app could be a possible 212 // On ARC enabled machines, either a tab or an app could be a possible
239 // victim of low memory kill process. This is a helper struct which holds a 213 // victim of low memory kill process. This is a helper class which holds a
240 // pointer to an app or a tab (but not both) to facilitate prioritizing the 214 // pointer to an app or a tab (but not both) to facilitate prioritizing the
241 // victims. 215 // victims.
242 struct TabManagerDelegate::Candidate { 216 class TabManagerDelegate::Candidate {
243 Candidate(const TabStats* _tab, int _priority) 217 public:
244 : tab(_tab), priority(_priority), is_arc_app(false) {} 218 explicit Candidate(const TabStats* tab)
245 Candidate(const arc::ArcProcess* _app, int _priority) 219 : tab_(tab), app_(nullptr), process_type_(GetProcessType()) {
246 : app(_app), priority(_priority), is_arc_app(true) {} 220 }
Yusuke Sato 2016/07/15 00:55:05 DCHECK(tab_)?
cylee1 2016/07/15 17:31:13 Done.
221 explicit Candidate(const arc::ArcProcess* app)
222 : tab_(nullptr), app_(app), process_type_(GetProcessType()) {
223 }
Yusuke Sato 2016/07/15 00:55:05 DCHECK(app_)?
cylee1 2016/07/15 17:31:13 Done.
247 224
248 bool operator<(const Candidate& rhs) const { return priority < rhs.priority; } 225 // Higher priority first.
226 bool operator<(const Candidate& rhs) const {
Yusuke Sato 2016/07/15 00:55:05 Can you move the implementation to .cc? The implem
cylee1 2016/07/15 17:31:13 Done.
227 if (process_type() != rhs.process_type())
228 return process_type() < rhs.process_type();
229 if (app() && rhs.app())
230 // Sort by (process_state, last_activity_time) pair.
231 // Smaller process_state value means higher priority as defined in
232 // Android.
233 // Larger last_activity_time means more recently used.
234 return std::make_pair(app()->process_state(),
Yusuke Sato 2016/07/15 00:55:05 What about adding CompareAppStats method to the ap
cylee1 2016/07/15 17:31:13 Moved to arc_process.cc .
235 -app()->last_activity_time()) <
236 std::make_pair(rhs.app()->process_state(),
237 -rhs.app()->last_activity_time());
238 if (tab() && rhs.tab())
239 return TabManager::CompareTabStats(*tab(), *rhs.tab());
240 // Impossible case. If app and tab are mixed in one process type, favor
241 // apps.
242 NOTREACHED() << "Undefined comparison between apps and tabs";
243 return app();
244 }
249 245
250 union { 246
251 const TabStats* tab; 247 const TabStats* tab() const { return tab_; }
252 const arc::ArcProcess* app; 248 const arc::ArcProcess* app() const { return app_; }
253 }; 249 ProcessType process_type() const { return process_type_; }
254 int priority; 250
255 bool is_arc_app; 251 private:
252 ProcessType GetProcessType() {
Yusuke Sato 2016/07/15 00:55:05 * This can be const. * Or better, can you make thi
cylee1 2016/07/15 17:31:13 Can I just use a const ? Passing all its member so
Luis Héctor Chávez 2016/07/15 18:10:06 Can you at the very least call this GetProcessType
Yusuke Sato 2016/07/19 01:31:36 Yeah, please rename it then.
cylee1 2016/07/20 17:57:53 Done.
cylee1 2016/07/20 17:57:53 Done.
253 if (app()) {
254 if (app()->is_focused())
255 return ProcessType::FOCUSED_APP;
256 if (app()->process_state() == arc::mojom::ProcessState::TOP)
257 return ProcessType::VISIBLE_APP;
258 return ProcessType::BACKGROUND_APP;
259 } else if (tab()) {
260 if (tab()->is_selected)
261 return ProcessType::FOCUSED_TAB;
262 return ProcessType::BACKGROUND_TAB;
263 }
264 NOTREACHED() << "Unexpected process type";
265 return ProcessType::UNKNOWN_TYPE;
266 }
267
268 const TabStats* tab_;
269 const arc::ArcProcess* app_;
270 ProcessType process_type_;
Yusuke Sato 2016/07/15 00:55:05 can be const too.
cylee1 2016/07/15 17:31:13 Because this class must allow copy and assign (use
256 }; 271 };
Yusuke Sato 2016/07/15 00:55:05 DISALLOW_COPY_AND_ASSIGN is missing.
cylee1 2016/07/15 17:31:13 This is used in a STL vector so it needs to allow
Luis Héctor Chávez 2016/07/15 18:10:06 non-copyable classes can be used in STL vectors. T
cylee1 2016/07/20 17:57:53 OK you're right. But do I need move() here given
cylee1 2016/07/22 22:18:43 I decided to drop the DISALLOW_COPY_AND_ASSIGN lin
Luis Héctor Chávez 2016/07/22 22:30:31 It should be slightly more efficient to make it no
cylee1 2016/07/22 23:14:40 Per IM discussion, reverted back to move assignmen
257 272
258 // A thin wrapper over library process_metric.h to get memory status so unit 273 // A thin wrapper over library process_metric.h to get memory status so unit
259 // test get a chance to mock out. 274 // test get a chance to mock out.
260 class TabManagerDelegate::MemoryStat { 275 class TabManagerDelegate::MemoryStat {
261 public: 276 public:
262 MemoryStat() {} 277 MemoryStat() {}
263 virtual ~MemoryStat() {} 278 virtual ~MemoryStat() {}
264 279
265 // Returns target size of memory to free given current memory pressure and 280 // Returns target size of memory to free given current memory pressure and
266 // pre-configured low memory margin. 281 // pre-configured low memory margin.
267 virtual int TargetMemoryToFreeKB(); 282 virtual int TargetMemoryToFreeKB();
268 283
269 // Returns estimated memory to be freed if the process |pid| is killed. 284 // Returns estimated memory to be freed if the process |pid| is killed.
270 virtual int EstimatedMemoryFreedKB(base::ProcessHandle pid); 285 virtual int EstimatedMemoryFreedKB(base::ProcessHandle pid);
271 286
272 private: 287 private:
273 // Returns the low memory margin system config. Low memory condition is 288 // Returns the low memory margin system config. Low memory condition is
274 // reported if available memory is under the number. 289 // reported if available memory is under the number.
275 static int LowMemoryMarginKB(); 290 static int LowMemoryMarginKB();
276 291
277 // Reads in an integer. 292 // Reads in an integer.
278 static int ReadIntFromFile(const char* file_name, int default_val); 293 static int ReadIntFromFile(const char* file_name, int default_val);
279 }; 294 };
280 295
281 } // namespace memory 296 } // namespace memory
282 297
283 #endif // CHROME_BROWSER_MEMORY_TAB_MANAGER_DELEGATE_CHROMEOS_H_ 298 #endif // CHROME_BROWSER_MEMORY_TAB_MANAGER_DELEGATE_CHROMEOS_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698