1 // Copyright (c) 2011 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. 4 5 // This is the browser side of the cache manager, it tracks the activity of the 6 // render processes and allocates available memory cache resources. 7 8 #ifndef COMPONENTS_WEB_CACHE_BROWSER_WEB_CACHE_MANAGER_H_ 9 #define COMPONENTS_WEB_CACHE_BROWSER_WEB_CACHE_MANAGER_H_ 10 11 #include <list> 12 #include <map> 13 #include <set> 14 15 #include "base/basictypes.h" 16 #include "base/compiler_specific.h" 17 #include "base/gtest_prod_util.h" 18 #include "base/memory/weak_ptr.h" 19 #include "base/time/time.h" 20 #include "content/public/browser/notification_observer.h" 21 #include "content/public/browser/notification_registrar.h" 22 #include "third_party/WebKit/public/web/WebCache.h" 23 24 template<typename Type> 25 struct DefaultSingletonTraits; 26 class PrefRegistrySimple; 27 28 namespace web_cache { 29 30 class WebCacheManager : public content::NotificationObserver { 31 friend class WebCacheManagerTest; 32 FRIEND_TEST_ALL_PREFIXES( 33 WebCacheManagerTest, 34 CallRemoveRendererAndObserveActivityInAnyOrderShouldNotCrashTest_1); 35 FRIEND_TEST_ALL_PREFIXES( 36 WebCacheManagerTest, 37 CallRemoveRendererAndObserveActivityInAnyOrderShouldNotCrashTest_2); 38 FRIEND_TEST_ALL_PREFIXES( 39 WebCacheManagerTest, 40 CallRemoveRendererAndObserveActivityInAnyOrderShouldNotCrashTest_3); 41 FRIEND_TEST_ALL_PREFIXES( 42 WebCacheManagerTest, 43 CallRemoveRendererAndObserveActivityInAnyOrderShouldNotCrashTest_4); 44 FRIEND_TEST_ALL_PREFIXES( 45 WebCacheManagerTest, 46 CallRemoveRendererAndObserveActivityInAnyOrderShouldNotCrashTest_5); 47 FRIEND_TEST_ALL_PREFIXES( 48 WebCacheManagerTest, 49 CallRemoveRendererAndObserveActivityInAnyOrderShouldNotCrashTest_6); 50 51 public: 52 // Gets the singleton WebCacheManager object. The first time this method 53 // is called, a WebCacheManager object is constructed and returned. 54 // Subsequent calls will return the same object. 55 static WebCacheManager* GetInstance(); 56 57 // When a render process is created, it registers itself with the cache 58 // manager host, causing the renderer to be allocated cache resources. 59 void Add(int renderer_id); 60 61 // When a render process ends, it removes itself from the cache manager host, 62 // freeing the manager to assign its cache resources to other renderers. 63 void Remove(int renderer_id); 64 65 // The cache manager assigns more cache resources to active renderer. When a 66 // renderer is active, it should inform the cache manager to receive more 67 // cache resources. 68 // 69 // When a renderer moves from being inactive to being active, the cache 70 // manager may decide to adjust its resource allocation, but it will delay 71 // the recalculation, allowing ObserveActivity to return quickly. 72 void ObserveActivity(int renderer_id); 73 74 // Periodically, renderers should inform the cache manager of their current 75 // statistics. The more up-to-date the cache manager's statistics, the 76 // better it can allocate cache resources. 77 void ObserveStats( 78 int renderer_id, const blink::WebCache::UsageStats& stats); 79 80 // The global limit on the number of bytes in all the in-memory caches. 81 size_t global_size_limit() const { return global_size_limit_; } 82 83 // Sets the global size limit, forcing a recalculation of cache allocations. 84 void SetGlobalSizeLimit(size_t bytes); 85 86 // Clears all in-memory caches. 87 void ClearCache(); 88 89 // Clears all in-memory caches when a tab is reloaded or the user navigates 90 // to a different website. 91 void ClearCacheOnNavigation(); 92 93 // content::NotificationObserver implementation: 94 virtual void Observe(int type, 95 const content::NotificationSource& source, 96 const content::NotificationDetails& details) OVERRIDE; 97 98 // Gets the default global size limit. This interrogates system metrics to 99 // tune the default size to the current system. 100 static size_t GetDefaultGlobalSizeLimit(); 101 102 protected: 103 // The amount of idle time before we consider a tab to be "inactive" 104 static const int kRendererInactiveThresholdMinutes = 5; 105 106 // Keep track of some renderer information. 107 struct RendererInfo : blink::WebCache::UsageStats { 108 // The access time for this renderer. 109 base::Time access; 110 }; 111 112 typedef std::map<int, RendererInfo> StatsMap; 113 114 // An allocation is the number of bytes a specific renderer should use for 115 // its cache. 116 typedef std::pair<int,size_t> Allocation; 117 118 // An allocation strategy is a list of allocations specifying the resources 119 // each renderer is permitted to consume for its cache. 120 typedef std::list<Allocation> AllocationStrategy; 121 122 // This class is a singleton. Do not instantiate directly. 123 WebCacheManager(); 124 friend struct DefaultSingletonTraits<WebCacheManager>; 125 126 virtual ~WebCacheManager(); 127 128 // Recomputes the allocation of cache resources among the renderers. Also 129 // informs the renderers of their new allocation. 130 void ReviseAllocationStrategy(); 131 132 // Schedules a call to ReviseAllocationStrategy after a short delay. 133 void ReviseAllocationStrategyLater(); 134 135 // The various tactics used as part of an allocation strategy. To decide 136 // how many resources a given renderer should be allocated, we consider its 137 // usage statistics. Each tactic specifies the function that maps usage 138 // statistics to resource allocations. 139 // 140 // Determining a resource allocation strategy amounts to picking a tactic 141 // for each renderer and checking that the total memory required fits within 142 // our |global_size_limit_|. 143 enum AllocationTactic { 144 // Ignore cache statistics and divide resources equally among the given 145 // set of caches. 146 DIVIDE_EVENLY, 147 148 // Allow each renderer to keep its current set of cached resources, with 149 // some extra allocation to store new objects. 150 KEEP_CURRENT_WITH_HEADROOM, 151 152 // Allow each renderer to keep its current set of cached resources. 153 KEEP_CURRENT, 154 155 // Allow each renderer to keep cache resources it believes are currently 156 // being used, with some extra allocation to store new objects. 157 KEEP_LIVE_WITH_HEADROOM, 158 159 // Allow each renderer to keep cache resources it believes are currently 160 // being used, but instruct the renderer to discard all other data. 161 KEEP_LIVE, 162 }; 163 164 // Helper functions for devising an allocation strategy 165 166 // Add up all the stats from the given set of renderers and place the result 167 // in |stats|. 168 void GatherStats(const std::set<int>& renderers, 169 blink::WebCache::UsageStats* stats); 170 171 // Get the amount of memory that would be required to implement |tactic| 172 // using the specified allocation tactic. This function defines the 173 // semantics for each of the tactics. 174 static size_t GetSize(AllocationTactic tactic, 175 const blink::WebCache::UsageStats& stats); 176 177 // Attempt to use the specified tactics to compute an allocation strategy 178 // and place the result in |strategy|. |active_stats| and |inactive_stats| 179 // are the aggregate statistics for |active_renderers_| and 180 // |inactive_renderers_|, respectively. 181 // 182 // Returns |true| on success and |false| on failure. Does not modify 183 // |strategy| on failure. 184 bool AttemptTactic(AllocationTactic active_tactic, 185 const blink::WebCache::UsageStats& active_stats, 186 AllocationTactic inactive_tactic, 187 const blink::WebCache::UsageStats& inactive_stats, 188 AllocationStrategy* strategy); 189 190 // For each renderer in |renderers|, computes its allocation according to 191 // |tactic| and add the result to |strategy|. Any |extra_bytes_to_allocate| 192 // is divided evenly among the renderers. 193 void AddToStrategy(const std::set<int>& renderers, 194 AllocationTactic tactic, 195 size_t extra_bytes_to_allocate, 196 AllocationStrategy* strategy); 197 198 // Enact an allocation strategy by informing the renderers of their 199 // allocations according to |strategy|. 200 void EnactStrategy(const AllocationStrategy& strategy); 201 202 enum ClearCacheOccasion { 203 // Instructs to clear the cache instantly. 204 INSTANTLY, 205 // Instructs to clear the cache when a navigation takes place (this 206 // includes reloading a tab). 207 ON_NAVIGATION 208 }; 209 210 // Inform all |renderers| to clear their cache. 211 void ClearRendererCache(const std::set<int>& renderers, 212 ClearCacheOccasion occation); 213 214 // Check to see if any active renderers have fallen inactive. 215 void FindInactiveRenderers(); 216 217 // The global size limit for all in-memory caches. 218 size_t global_size_limit_; 219 220 // Maps every renderer_id our most recent copy of its statistics. 221 StatsMap stats_; 222 223 // Every renderer we think is still around is in one of these two sets. 224 // 225 // Active renderers are those renderers that have been active more recently 226 // than they have been inactive. 227 std::set<int> active_renderers_; 228 // Inactive renderers are those renderers that have been inactive more 229 // recently than they have been active. 230 std::set<int> inactive_renderers_; 231 232 content::NotificationRegistrar registrar_; 233 234 base::WeakPtrFactory<WebCacheManager> weak_factory_; 235 236 DISALLOW_COPY_AND_ASSIGN(WebCacheManager); 237 }; 238 239 } // namespace web_cache 240 241 #endif // COMPONENTS_WEB_CACHE_BROWSER_WEB_CACHE_MANAGER_H_ 242