| 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);
|
| };
|
|
|
|
|