Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef BASE_MEMORY_DISCARDABLE_MEMORY_MANAGER_H_ | 5 #ifndef BASE_MEMORY_DISCARDABLE_MEMORY_MANAGER_H_ |
| 6 #define BASE_MEMORY_DISCARDABLE_MEMORY_MANAGER_H_ | 6 #define BASE_MEMORY_DISCARDABLE_MEMORY_MANAGER_H_ |
| 7 | 7 |
| 8 #include "base/base_export.h" | 8 #include "base/base_export.h" |
| 9 #include "base/containers/hash_tables.h" | 9 #include "base/containers/hash_tables.h" |
| 10 #include "base/containers/mru_cache.h" | 10 #include "base/containers/mru_cache.h" |
| 11 #include "base/memory/memory_pressure_listener.h" | 11 #include "base/memory/memory_pressure_listener.h" |
| 12 #include "base/synchronization/lock.h" | 12 #include "base/synchronization/lock.h" |
| 13 #include "base/time/time.h" | |
| 13 | 14 |
| 14 namespace base { | 15 namespace base { |
| 15 namespace internal { | 16 namespace internal { |
| 16 | 17 |
| 17 // This interface is used by the DiscardableMemoryManager class to provide some | 18 // This interface is used by the DiscardableMemoryManager class to provide some |
| 18 // level of userspace control over discardable memory allocations. | 19 // level of userspace control over discardable memory allocations. |
| 19 class DiscardableMemoryManagerAllocation { | 20 class DiscardableMemoryManagerAllocation { |
| 20 public: | 21 public: |
| 21 // Allocate and acquire a lock that prevents the allocation from being purged | 22 // Allocate and acquire a lock that prevents the allocation from being purged |
| 22 // by the system. Returns true if memory was previously allocated and is still | 23 // by the system. Returns true if memory was previously allocated and is still |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 56 // The DiscardableMemoryManager manages a collection of | 57 // The DiscardableMemoryManager manages a collection of |
| 57 // DiscardableMemoryManagerAllocation instances. It is used on platforms that | 58 // DiscardableMemoryManagerAllocation instances. It is used on platforms that |
| 58 // need some level of userspace control over discardable memory. It keeps track | 59 // need some level of userspace control over discardable memory. It keeps track |
| 59 // of all allocation instances (in case they need to be purged), and the total | 60 // of all allocation instances (in case they need to be purged), and the total |
| 60 // amount of allocated memory (in case this forces a purge). When memory usage | 61 // amount of allocated memory (in case this forces a purge). When memory usage |
| 61 // reaches the limit, the manager purges the LRU memory. | 62 // reaches the limit, the manager purges the LRU memory. |
| 62 // | 63 // |
| 63 // When notified of memory pressure, the manager either purges the LRU memory -- | 64 // When notified of memory pressure, the manager either purges the LRU memory -- |
| 64 // if the pressure is moderate -- or all discardable memory if the pressure is | 65 // if the pressure is moderate -- or all discardable memory if the pressure is |
| 65 // critical. | 66 // critical. |
| 67 // | |
| 68 // When notified that idle, the manager purges memory not used since the hard | |
| 69 // memory limit cutoff. | |
| 66 class BASE_EXPORT_PRIVATE DiscardableMemoryManager { | 70 class BASE_EXPORT_PRIVATE DiscardableMemoryManager { |
| 67 public: | 71 public: |
| 68 typedef DiscardableMemoryManagerAllocation Allocation; | 72 typedef DiscardableMemoryManagerAllocation Allocation; |
| 69 | 73 |
| 70 DiscardableMemoryManager(size_t memory_limit, | 74 DiscardableMemoryManager(size_t memory_limit, |
| 71 size_t bytes_to_keep_under_moderate_pressure); | 75 size_t soft_memory_limit, |
| 72 ~DiscardableMemoryManager(); | 76 size_t bytes_to_keep_under_moderate_pressure, |
| 77 TimeDelta hard_memory_limit_expiration_time); | |
| 78 virtual ~DiscardableMemoryManager(); | |
| 73 | 79 |
| 74 // Call this to register memory pressure listener. Must be called on a thread | 80 // Call this to register memory pressure listener. Must be called on a thread |
| 75 // with a MessageLoop current. | 81 // with a MessageLoop current. |
| 76 void RegisterMemoryPressureListener(); | 82 void RegisterMemoryPressureListener(); |
| 77 | 83 |
| 78 // Call this to unregister memory pressure listener. | 84 // Call this to unregister memory pressure listener. |
| 79 void UnregisterMemoryPressureListener(); | 85 void UnregisterMemoryPressureListener(); |
| 80 | 86 |
| 81 // The maximum number of bytes of memory that may be allocated before we force | 87 // The maximum number of bytes of memory that may be allocated before we force |
| 82 // a purge. If this amount is zero, it is interpreted as having no limit at | 88 // a purge. |
| 83 // all. | |
| 84 void SetMemoryLimit(size_t bytes); | 89 void SetMemoryLimit(size_t bytes); |
| 85 | 90 |
| 91 // The number of bytes of memory that may be allocated but unused for the hard | |
| 92 // limit expiration time without getting purged. | |
| 93 void SetSoftMemoryLimit(size_t bytes); | |
| 94 | |
| 86 // Sets the amount of memory to keep when we're under moderate pressure. | 95 // Sets the amount of memory to keep when we're under moderate pressure. |
| 87 void SetBytesToKeepUnderModeratePressure(size_t bytes); | 96 void SetBytesToKeepUnderModeratePressure(size_t bytes); |
| 88 | 97 |
| 98 // Sets the memory usage cutoff time for hard memory limit. | |
| 99 void SetHardMemoryLimitExpirationTime( | |
| 100 TimeDelta hard_memory_limit_expiration_time); | |
| 101 | |
| 102 // Call this when idle. Will attempt to reduce memory footprint until within | |
| 103 // soft memory limit. | |
| 104 // Returns true if there's no need to call this again until allocations | |
| 105 // have been used. | |
| 106 bool IdleNotification(); | |
| 107 | |
| 89 // Adds the given allocation to the manager's collection. | 108 // Adds the given allocation to the manager's collection. |
| 90 void Register(Allocation* allocation, size_t bytes); | 109 void Register(Allocation* allocation, size_t bytes); |
| 91 | 110 |
| 92 // Removes the given allocation from the manager's collection. | 111 // Removes the given allocation from the manager's collection. |
| 93 void Unregister(Allocation* allocation); | 112 void Unregister(Allocation* allocation); |
| 94 | 113 |
| 95 // Returns false if an error occurred. Otherwise, returns true and sets | 114 // Returns false if an error occurred. Otherwise, returns true and sets |
| 96 // |purged| to indicate whether or not allocation has been purged since last | 115 // |purged| to indicate whether or not allocation has been purged since last |
| 97 // use. | 116 // use. |
| 98 bool AcquireLock(Allocation* allocation, bool* purged); | 117 bool AcquireLock(Allocation* allocation, bool* purged); |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 109 bool IsRegisteredForTest(Allocation* allocation) const; | 128 bool IsRegisteredForTest(Allocation* allocation) const; |
| 110 | 129 |
| 111 // Returns true if allocation can be purged. This should only be used by | 130 // Returns true if allocation can be purged. This should only be used by |
| 112 // tests. | 131 // tests. |
| 113 bool CanBePurgedForTest(Allocation* allocation) const; | 132 bool CanBePurgedForTest(Allocation* allocation) const; |
| 114 | 133 |
| 115 // Returns total amount of allocated discardable memory. This should only be | 134 // Returns total amount of allocated discardable memory. This should only be |
| 116 // used by tests. | 135 // used by tests. |
| 117 size_t GetBytesAllocatedForTest() const; | 136 size_t GetBytesAllocatedForTest() const; |
| 118 | 137 |
| 138 protected: | |
|
willchan no longer on Chromium
2014/06/27 14:12:57
I don't think this needs to be protected. Private
reveman
2014/06/27 20:38:02
Done.
| |
| 139 // Virtual for tests. | |
| 140 virtual TimeTicks Now() const; | |
| 141 | |
| 119 private: | 142 private: |
| 120 struct AllocationInfo { | 143 struct AllocationInfo { |
| 121 explicit AllocationInfo(size_t bytes) : bytes(bytes), purgable(false) {} | 144 explicit AllocationInfo(size_t bytes) : bytes(bytes), purgable(false) {} |
| 122 | 145 |
| 123 const size_t bytes; | 146 const size_t bytes; |
| 124 bool purgable; | 147 bool purgable; |
| 148 TimeTicks last_usage; | |
| 125 }; | 149 }; |
| 126 typedef HashingMRUCache<Allocation*, AllocationInfo> AllocationMap; | 150 typedef HashingMRUCache<Allocation*, AllocationInfo> AllocationMap; |
| 127 | 151 |
| 128 // This can be called as a hint that the system is under memory pressure. | 152 // This can be called as a hint that the system is under memory pressure. |
| 129 void OnMemoryPressure( | 153 void OnMemoryPressure( |
| 130 MemoryPressureListener::MemoryPressureLevel pressure_level); | 154 MemoryPressureListener::MemoryPressureLevel pressure_level); |
| 131 | 155 |
| 132 // Purges memory until usage is within | 156 // Purges memory until usage is less or equal to |
| 133 // |bytes_to_keep_under_moderate_pressure_|. | 157 // |bytes_to_keep_under_moderate_pressure_|. |
| 134 void Purge(); | 158 void PurgeUntilWithinBytesToKeepUnderModeratePressure(); |
| 135 | 159 |
| 136 // Purges least recently used memory until usage is less or equal to |limit|. | 160 // Purges memory not used since |hard_memory_limit_expiration_time_| before |
| 161 // "right now" until usage is less or equal to |soft_memory_limit_|. | |
| 162 // Returns true if total amount of memory is less or equal to soft memory | |
| 163 // limit. | |
| 164 bool PurgeIfNotUsedSinceHardLimitCutoffUntilWithinSoftMemoryLimit(); | |
| 165 | |
| 166 // Purges memory that has not been used since |timestamp| until usage is less | |
| 167 // or equal to |limit|. | |
| 137 // Caller must acquire |lock_| prior to calling this function. | 168 // Caller must acquire |lock_| prior to calling this function. |
| 138 void PurgeLRUWithLockAcquiredUntilUsageIsWithin(size_t limit); | 169 void PurgeIfNotUsedSinceTimestampUntilUsageIsWithinLimitWithLockAcquired( |
|
willchan no longer on Chromium
2014/06/24 16:33:00
Nice function name.
| |
| 139 | 170 TimeTicks timestamp, |
| 140 // Ensures that we don't allocate beyond our memory limit. Caller must acquire | 171 size_t limit); |
| 141 // |lock_| prior to calling this function. | |
| 142 void EnforcePolicyWithLockAcquired(); | |
| 143 | 172 |
| 144 // Called when a change to |bytes_allocated_| has been made. | 173 // Called when a change to |bytes_allocated_| has been made. |
| 145 void BytesAllocatedChanged() const; | 174 void BytesAllocatedChanged(size_t new_bytes_allocated) const; |
|
willchan no longer on Chromium
2014/06/27 14:12:57
Why is it necessary to pass this? If it's better f
reveman
2014/06/27 20:38:02
This function previously assumed that it was alway
| |
| 146 | 175 |
| 147 // Needs to be held when accessing members. | 176 // Needs to be held when accessing members. |
| 148 mutable Lock lock_; | 177 mutable Lock lock_; |
| 149 | 178 |
| 150 // A MRU cache of all allocated bits of memory. Used for purging. | 179 // A MRU cache of all allocated bits of memory. Used for purging. |
| 151 AllocationMap allocations_; | 180 AllocationMap allocations_; |
| 152 | 181 |
| 153 // The total amount of allocated memory. | 182 // The total amount of allocated memory. |
| 154 size_t bytes_allocated_; | 183 size_t bytes_allocated_; |
| 155 | 184 |
| 156 // The maximum number of bytes of memory that may be allocated. | 185 // The maximum number of bytes of memory that may be allocated. |
| 157 size_t memory_limit_; | 186 size_t memory_limit_; |
| 158 | 187 |
| 188 // The number of bytes of memory that may be allocated but not used for | |
| 189 // |hard_memory_limit_expiration_time_| amount of time when receiving an idle | |
| 190 // notification. | |
| 191 size_t soft_memory_limit_; | |
| 192 | |
| 159 // Under moderate memory pressure, we will purge memory until usage is within | 193 // Under moderate memory pressure, we will purge memory until usage is within |
| 160 // this limit. | 194 // this limit. |
| 161 size_t bytes_to_keep_under_moderate_pressure_; | 195 size_t bytes_to_keep_under_moderate_pressure_; |
| 162 | 196 |
| 163 // Allows us to be respond when the system reports that it is under memory | 197 // Allows us to be respond when the system reports that it is under memory |
| 164 // pressure. | 198 // pressure. |
| 165 scoped_ptr<MemoryPressureListener> memory_pressure_listener_; | 199 scoped_ptr<MemoryPressureListener> memory_pressure_listener_; |
| 166 | 200 |
| 201 // Amount of time it takes for an allocation to become affected by | |
| 202 // |soft_memory_limit_|. | |
| 203 TimeDelta hard_memory_limit_expiration_time_; | |
| 204 | |
| 167 DISALLOW_COPY_AND_ASSIGN(DiscardableMemoryManager); | 205 DISALLOW_COPY_AND_ASSIGN(DiscardableMemoryManager); |
| 168 }; | 206 }; |
| 169 | 207 |
| 170 } // namespace internal | 208 } // namespace internal |
| 171 } // namespace base | 209 } // namespace base |
| 172 | 210 |
| 173 #endif // BASE_MEMORY_DISCARDABLE_MEMORY_MANAGER_H_ | 211 #endif // BASE_MEMORY_DISCARDABLE_MEMORY_MANAGER_H_ |
| OLD | NEW |