Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / chromeos / memory / oom_priority_manager.h
blob3df538ebddccb3b144de5fe257e24bc50e6f3677
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
3 // found in the LICENSE file.
5 #ifndef CHROME_BROWSER_CHROMEOS_MEMORY_OOM_PRIORITY_MANAGER_H_
6 #define CHROME_BROWSER_CHROMEOS_MEMORY_OOM_PRIORITY_MANAGER_H_
8 #include <vector>
10 #include "base/compiler_specific.h"
11 #include "base/containers/hash_tables.h"
12 #include "base/gtest_prod_util.h"
13 #include "base/memory/scoped_ptr.h"
14 #include "base/process/process.h"
15 #include "base/strings/string16.h"
16 #include "base/synchronization/lock.h"
17 #include "base/time/time.h"
18 #include "base/timer/timer.h"
19 #include "chromeos/memory/low_memory_listener_delegate.h"
20 #include "content/public/browser/notification_observer.h"
21 #include "content/public/browser/notification_registrar.h"
23 class GURL;
25 namespace chromeos {
27 class LowMemoryListener;
29 // The OomPriorityManager periodically checks (see
30 // ADJUSTMENT_INTERVAL_SECONDS in the source) the status of renderers
31 // and adjusts the out of memory (OOM) adjustment value (in
32 // /proc/<pid>/oom_score_adj) of the renderers so that they match the
33 // algorithm embedded here for priority in being killed upon OOM
34 // conditions.
36 // The algorithm used favors killing tabs that are not selected, not pinned,
37 // and have been idle for longest, in that order of priority.
38 class OomPriorityManager : public content::NotificationObserver,
39 public LowMemoryListenerDelegate {
40 public:
41 OomPriorityManager();
42 virtual ~OomPriorityManager();
44 // Number of discard events since Chrome started.
45 int discard_count() const { return discard_count_; }
47 // See member comment.
48 bool recent_tab_discard() const { return recent_tab_discard_; }
50 void Start();
51 void Stop();
53 // Returns list of tab titles sorted from most interesting (don't kill)
54 // to least interesting (OK to kill).
55 std::vector<base::string16> GetTabTitles();
57 // Discards a tab to free the memory occupied by its renderer.
58 // Tab still exists in the tab-strip; clicking on it will reload it.
59 // Returns true if it successfully found a tab and discarded it.
60 bool DiscardTab();
62 // Log memory statistics for the running processes, then discards a tab.
63 // Tab discard happens sometime later, as collecting the statistics touches
64 // multiple threads and takes time.
65 void LogMemoryAndDiscardTab();
67 private:
68 friend class OomMemoryDetails;
69 FRIEND_TEST_ALL_PREFIXES(OomPriorityManagerTest, Comparator);
70 FRIEND_TEST_ALL_PREFIXES(OomPriorityManagerTest, IsReloadableUI);
72 struct TabStats {
73 TabStats();
74 ~TabStats();
75 bool is_app; // browser window is an app
76 bool is_reloadable_ui; // Reloadable web UI page, like NTP or Settings.
77 bool is_playing_audio;
78 bool is_pinned;
79 bool is_selected; // selected in the currently active browser window
80 bool is_discarded;
81 base::TimeTicks last_selected;
82 base::ProcessHandle renderer_handle;
83 base::string16 title;
84 int64 tab_contents_id; // unique ID per WebContents
86 typedef std::vector<TabStats> TabStatsList;
88 // Returns true if the |url| represents an internal Chrome web UI page that
89 // can be easily reloaded and hence makes a good choice to discard.
90 static bool IsReloadableUI(const GURL& url);
92 // Discards a tab with the given unique ID. Returns true if discard occurred.
93 bool DiscardTabById(int64 target_web_contents_id);
95 // Records UMA histogram statistics for a tab discard. We record statistics
96 // for user triggered discards via chrome://discards/ because that allows us
97 // to manually test the system.
98 void RecordDiscardStatistics();
100 // Record whether we ran out of memory during a recent time interval.
101 // This allows us to normalize low memory statistics versus usage.
102 void RecordRecentTabDiscard();
104 // Purges data structures in the browser that can be easily recomputed.
105 void PurgeBrowserMemory();
107 // Returns the number of tabs open in all browser instances.
108 int GetTabCount() const;
110 TabStatsList GetTabStatsOnUIThread();
112 // Called when the timer fires, sets oom_adjust_score for all renderers.
113 void AdjustOomPriorities();
115 // Called by AdjustOomPriorities.
116 void AdjustOomPrioritiesOnFileThread(TabStatsList stats_list);
118 // Posts AdjustFocusedTabScore task to the file thread.
119 void OnFocusTabScoreAdjustmentTimeout();
121 // Sets the score of the focused tab to the least value.
122 void AdjustFocusedTabScoreOnFileThread();
124 static bool CompareTabStats(TabStats first, TabStats second);
126 // NotificationObserver overrides:
127 virtual void Observe(int type,
128 const content::NotificationSource& source,
129 const content::NotificationDetails& details) OVERRIDE;
131 // LowMemoryListenerDelegate overrides:
132 virtual void OnMemoryLow() OVERRIDE;
134 base::RepeatingTimer<OomPriorityManager> timer_;
135 base::OneShotTimer<OomPriorityManager> focus_tab_score_adjust_timer_;
136 base::RepeatingTimer<OomPriorityManager> recent_tab_discard_timer_;
137 content::NotificationRegistrar registrar_;
139 // This lock is for pid_to_oom_score_ and focus_tab_pid_.
140 base::Lock pid_to_oom_score_lock_;
141 // map maintaining the process - oom_score mapping.
142 typedef base::hash_map<base::ProcessHandle, int> ProcessScoreMap;
143 ProcessScoreMap pid_to_oom_score_;
144 base::ProcessHandle focused_tab_pid_;
146 // Observer for the kernel low memory signal.
147 scoped_ptr<LowMemoryListener> low_memory_listener_;
149 // Wall-clock time when the priority manager started running.
150 base::TimeTicks start_time_;
152 // Wall-clock time of last tab discard during this browsing session, or 0 if
153 // no discard has happened yet.
154 base::TimeTicks last_discard_time_;
156 // Wall-clock time of last priority adjustment, used to correct the above
157 // times for discontinuities caused by suspend/resume.
158 base::TimeTicks last_adjust_time_;
160 // Number of times we have discarded a tab, for statistics.
161 int discard_count_;
163 // Whether a tab discard event has occurred during the last time interval,
164 // used for statistics normalized by usage.
165 bool recent_tab_discard_;
167 DISALLOW_COPY_AND_ASSIGN(OomPriorityManager);
170 } // namespace chromeos
172 #endif // CHROME_BROWSER_CHROMEOS_MEMORY_OOM_PRIORITY_MANAGER_H_