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

Unified Diff: chrome/browser/memory/tab_manager.h

Issue 1641813002: Provide renderers with memory pressure signals. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@contentapi
Patch Set: Addressed creis' comments. Created 4 years, 11 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | chrome/browser/memory/tab_manager.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/memory/tab_manager.h
diff --git a/chrome/browser/memory/tab_manager.h b/chrome/browser/memory/tab_manager.h
index 181e2bffff5f50ece2ad1dd44416bc5d1a2f6db8..99f3ba5d38210c9118566c1a12023dc28a41c66b 100644
--- a/chrome/browser/memory/tab_manager.h
+++ b/chrome/browser/memory/tab_manager.h
@@ -7,15 +7,19 @@
#include <stdint.h>
+#include <set>
#include <utility>
#include <vector>
+#include "base/callback.h"
#include "base/compiler_specific.h"
#include "base/gtest_prod_util.h"
#include "base/macros.h"
#include "base/memory/memory_pressure_listener.h"
#include "base/memory/scoped_ptr.h"
+#include "base/memory/weak_ptr.h"
#include "base/strings/string16.h"
+#include "base/task_runner.h"
#include "base/timer/timer.h"
#include "build/build_config.h"
#include "chrome/browser/memory/tab_stats.h"
@@ -24,12 +28,14 @@
class BrowserList;
class GURL;
+class TabStripModel;
namespace base {
class TickClock;
}
namespace content {
+class RenderProcessHost;
class WebContents;
}
@@ -78,6 +84,9 @@ class TabManager : public TabStripModelObserver {
// thread.
TabStatsList GetTabStats();
+ // Returns a sorted list of renderers, from most important to least important.
+ std::vector<content::RenderProcessHost*> GetOrderedRenderers();
+
// Returns true if |contents| is currently discarded.
bool IsTabDiscarded(content::WebContents* contents) const;
@@ -104,6 +113,7 @@ class TabManager : public TabStripModelObserver {
void set_test_tick_clock(base::TickClock* test_tick_clock);
private:
+ FRIEND_TEST_ALL_PREFIXES(TabManagerTest, ChildProcessNotifications);
FRIEND_TEST_ALL_PREFIXES(TabManagerTest, Comparator);
FRIEND_TEST_ALL_PREFIXES(TabManagerTest, DiscardedTabKeepsLastActiveTime);
FRIEND_TEST_ALL_PREFIXES(TabManagerTest, DiscardWebContentsAt);
@@ -112,6 +122,31 @@ class TabManager : public TabStripModelObserver {
FRIEND_TEST_ALL_PREFIXES(TabManagerTest, ReloadDiscardedTabContextMenu);
FRIEND_TEST_ALL_PREFIXES(TabManagerTest, TabManagerBasics);
+ // The time that a renderer is given to react to a memory pressure
+ // notification before another renderer is also notified. This prevents all
+ // renderers from receiving and acting upon notifications simultaneously,
+ // which can quickly overload a system. Exposed for unittesting.
+ // NOTE: This value needs to be big enough to allow a process to get over the
+ // hump in responding to memory pressure, so there aren't multiple processes
+ // fighting for CPU and worse, temporary memory, while trying to free things
+ // up. Similarly, it shouldn't be too large otherwise it will take too long
+ // for the entire system to respond. Ideally, there would be a callback from a
+ // child process indicating that the message has been handled. In the meantime
+ // this is chosen to be sufficient to allow a worst-case V8+Oilpan GC to run,
+ // with a little slop.
+ enum : int { kRendererNotificationDelayInSeconds = 2 };
+
+ using MemoryPressureLevel = base::MemoryPressureListener::MemoryPressureLevel;
+
+ // A callback that returns the current memory pressure level.
+ using MemoryPressureLevelCallback = base::Callback<MemoryPressureLevel()>;
+
+ // Callback that notifies a |renderer| of the memory pressure at a given
+ // |level|. Provides a testing seam.
+ using RendererNotificationCallback = base::Callback<
+ void(const content::RenderProcessHost* /* renderer */,
+ MemoryPressureLevel /* level */)>;
+
static void PurgeMemoryAndDiscardTab();
// Returns true if the |url| represents an internal Chrome web UI page that
@@ -136,6 +171,13 @@ class TabManager : public TabStripModelObserver {
// Adds all the stats of the tabs to |stats_list|.
void AddTabStats(TabStatsList* stats_list);
+ // Adds all the stats of the tabs in |tab_strip_model| into |stats_list|.
+ // If |active_model| is true, consider its first tab as being active.
+ void AddTabStats(const TabStripModel* model,
+ bool is_app,
+ bool active_model,
+ TabStatsList* stats_list);
+
// Callback for when |update_timer_| fires. Takes care of executing the tasks
// that need to be run periodically (see comment in implementation).
void UpdateTimerCallback();
@@ -180,6 +222,10 @@ class TabManager : public TabStripModelObserver {
// for more details.
base::TimeTicks NowTicks() const;
+ // Dispatches a memory pressure message to a single child process, and
+ // schedules another call to itself as long as memory pressure continues.
+ void DoChildProcessDispatch();
+
// Timer to periodically update the stats of the renderers.
base::RepeatingTimer update_timer_;
@@ -219,12 +265,51 @@ class TabManager : public TabStripModelObserver {
scoped_ptr<TabManagerDelegate> delegate_;
#endif
+ // Responsible for automatically registering this class as an observer of all
+ // TabStripModels. Automatically tracks browsers as they come and go.
BrowserTabStripTracker browser_tab_strip_tracker_;
// Pointer to a test clock. If this is set, NowTicks() returns the value of
// this test clock. Otherwise it returns the system clock's value.
base::TickClock* test_tick_clock_;
+ // The task runner used for child process notifications. Defaults to the
+ // thread task runner handle that is used by the memory pressure subsystem,
+ // but may be explicitly set for unittesting.
+ scoped_refptr<base::TaskRunner> task_runner_;
+
+ // Indicates that the system is currently experiencing memory pressure. Used
+ // to determine whether a new round of child-process memory pressure
+ // dispatches is starting, or whether an existing one is continuing.
+ bool under_memory_pressure_;
+
+ // The set of child renderers that have received memory pressure notifications
+ // during the current bout of memory pressure. This is emptied when all
+ // children have been notified (restarting another round of notification) and
+ // when a bout of memory pressure ends.
+ std::set<const content::RenderProcessHost*> notified_renderers_;
+
+ // The callback that returns the current memory pressure level. Defaults to
+ // querying base::MemoryPressureMonitor, but can be overridden for testing.
+ MemoryPressureLevelCallback get_current_pressure_level_;
+
+ // The callback to be invoked to notify renderers. Defaults to calling
+ // content::SendPressureNotification, but can be overridden for testing.
+ RendererNotificationCallback notify_renderer_process_;
+
+ // Injected tab strip models. Allows this to be tested end-to-end without
+ // requiring a full browser environment. If specified these tab strips will be
+ // crawled as the authoritative source of tabs, otherwise the BrowserList and
+ // associated Browser objects are crawled. The first of these is considered to
+ // be the 'active' tab strip model.
+ // TODO(chrisha): Factor out tab-strip model enumeration to a helper class,
+ // and make a delegate that centralizes all testing seams.
+ using TestTabStripModel = std::pair<const TabStripModel*, bool>;
+ std::vector<TestTabStripModel> test_tab_strip_models_;
+
+ // Weak pointer factory used for posting delayed tasks to task_runner_.
+ base::WeakPtrFactory<TabManager> weak_ptr_factory_;
+
DISALLOW_COPY_AND_ASSIGN(TabManager);
};
« no previous file with comments | « no previous file | chrome/browser/memory/tab_manager.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698