Roll src/third_party/WebKit eac3800:0237a66 (svn 202606:202607)
[chromium-blink-merge.git] / chrome / browser / memory / oom_priority_manager.h
blob1b50a33ff25e6ec8287d7f72e733f7a8aa192143
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_MEMORY_OOM_PRIORITY_MANAGER_H_
6 #define CHROME_BROWSER_MEMORY_OOM_PRIORITY_MANAGER_H_
8 #include <utility>
9 #include <vector>
11 #include "base/compiler_specific.h"
12 #include "base/gtest_prod_util.h"
13 #include "base/memory/memory_pressure_listener.h"
14 #include "base/memory/scoped_ptr.h"
15 #include "base/strings/string16.h"
16 #include "base/timer/timer.h"
17 #include "chrome/browser/memory/tab_stats.h"
19 class BrowserList;
20 class GURL;
22 namespace memory {
24 #if defined(OS_CHROMEOS)
25 class OomPriorityManagerDelegate;
26 #endif
28 // The OomPriorityManager periodically updates (see
29 // |kAdjustmentIntervalSeconds| in the source) the status of renderers
30 // which are then used by the algorithm embedded here for priority in being
31 // killed upon OOM conditions.
33 // The algorithm used favors killing tabs that are not selected, not pinned,
34 // and have been idle for longest, in that order of priority.
36 // On Chrome OS (via the delegate), the kernel (via /proc/<pid>/oom_score_adj)
37 // will be informed of each renderer's score, which is based on the status, so
38 // in case Chrome is not able to relieve the pressure quickly enough and the
39 // kernel is forced to kill processes, it will be able to do so using the same
40 // algorithm as the one used here.
42 // Note that the browser tests are only active for platforms that use
43 // OomPriorityManager (CrOS only for now) and need to be adjusted accordingly if
44 // support for new platforms is added.
45 class OomPriorityManager {
46 public:
47 OomPriorityManager();
48 ~OomPriorityManager();
50 // Number of discard events since Chrome started.
51 int discard_count() const { return discard_count_; }
53 // See member comment.
54 bool recent_tab_discard() const { return recent_tab_discard_; }
56 // If |discard_once| is set, tabs that get discarded once will never get
57 // discarded again.
58 void Start(bool discard_once);
59 void Stop();
61 // Returns the list of the stats for all renderers. Must be called on the UI
62 // thread.
63 TabStatsList GetTabStats();
65 // Discards a tab to free the memory occupied by its renderer. The tab still
66 // exists in the tab-strip; clicking on it will reload it. Returns true if it
67 // successfully found a tab and discarded it.
68 bool DiscardTab();
70 // Discards a tab with the given unique ID. The tab still exists in the
71 // tab-strip; clicking on it will reload it. Returns true if it successfully
72 // found a tab and discarded it.
73 bool DiscardTabById(int64 target_web_contents_id);
75 // Log memory statistics for the running processes, then discards a tab.
76 // Tab discard happens sometime later, as collecting the statistics touches
77 // multiple threads and takes time.
78 void LogMemoryAndDiscardTab();
80 // Log memory statistics for the running processes, then call the callback.
81 void LogMemory(const std::string& title, const base::Closure& callback);
83 private:
84 FRIEND_TEST_ALL_PREFIXES(OomPriorityManagerTest, Comparator);
85 FRIEND_TEST_ALL_PREFIXES(OomPriorityManagerTest, IsInternalPage);
87 static void PurgeMemoryAndDiscardTab();
89 // Returns true if the |url| represents an internal Chrome web UI page that
90 // can be easily reloaded and hence makes a good choice to discard.
91 static bool IsInternalPage(const GURL& url);
93 // Records UMA histogram statistics for a tab discard. We record statistics
94 // for user triggered discards via chrome://discards/ because that allows us
95 // to manually test the system.
96 void RecordDiscardStatistics();
98 // Record whether we ran out of memory during a recent time interval.
99 // This allows us to normalize low memory statistics versus usage.
100 void RecordRecentTabDiscard();
102 // Purges data structures in the browser that can be easily recomputed.
103 void PurgeBrowserMemory();
105 // Returns the number of tabs open in all browser instances.
106 int GetTabCount() const;
108 // Adds all the stats of the tabs in |browser_list| into |stats_list|. If
109 // |active_desktop| is true, we consider its first window as being active.
110 void AddTabStats(BrowserList* browser_list,
111 bool active_desktop,
112 TabStatsList* stats_list);
114 // Callback for when |update_timer_| fires. Takes care of executing the tasks
115 // that need to be run periodically (see comment in implementation).
116 void UpdateTimerCallback();
118 // Goes through a list of checks to see if a tab is allowed to be discarded by
119 // the automatic tab discarding mechanism. Note that this is not used when
120 // discarding a particular tab from about:discards.
121 bool CanDiscardTab(int64 target_web_contents_id) const;
123 // Called by the memory pressure listener when the memory pressure rises.
124 void OnMemoryPressure(
125 base::MemoryPressureListener::MemoryPressureLevel memory_pressure_level);
127 // Returns true if |first| is considered less desirable to be killed than
128 // |second|.
129 static bool CompareTabStats(TabStats first, TabStats second);
131 // Timer to periodically update the stats of the renderers.
132 base::RepeatingTimer<OomPriorityManager> update_timer_;
134 // Timer to periodically report whether a tab has been discarded since the
135 // last time the timer has fired.
136 base::RepeatingTimer<OomPriorityManager> recent_tab_discard_timer_;
138 // A listener to global memory pressure events.
139 scoped_ptr<base::MemoryPressureListener> memory_pressure_listener_;
141 // Wall-clock time when the priority manager started running.
142 base::TimeTicks start_time_;
144 // Wall-clock time of last tab discard during this browsing session, or 0 if
145 // no discard has happened yet.
146 base::TimeTicks last_discard_time_;
148 // Wall-clock time of last priority adjustment, used to correct the above
149 // times for discontinuities caused by suspend/resume.
150 base::TimeTicks last_adjust_time_;
152 // Number of times we have discarded a tab, for statistics.
153 int discard_count_;
155 // Whether a tab discard event has occurred during the last time interval,
156 // used for statistics normalized by usage.
157 bool recent_tab_discard_;
159 // Whether we ever only discard a tab once.
160 bool discard_once_;
162 #if defined(OS_CHROMEOS)
163 scoped_ptr<OomPriorityManagerDelegate> delegate_;
164 #endif
166 DISALLOW_COPY_AND_ASSIGN(OomPriorityManager);
169 } // namespace memory
171 #endif // CHROME_BROWSER_MEMORY_OOM_PRIORITY_MANAGER_H_