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

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

Powered by Google App Engine
This is Rietveld 408576698