Index: base/memory/discardable_memory_manager.h |
diff --git a/base/memory/discardable_memory_manager.h b/base/memory/discardable_memory_manager.h |
index 8297b81b0408c2123ee6a141cc7435c4a0292875..002d5f563600e5c3466a8fadc5a15f067a78dc52 100644 |
--- a/base/memory/discardable_memory_manager.h |
+++ b/base/memory/discardable_memory_manager.h |
@@ -10,6 +10,7 @@ |
#include "base/containers/mru_cache.h" |
#include "base/memory/memory_pressure_listener.h" |
#include "base/synchronization/lock.h" |
+#include "base/time/time.h" |
namespace base { |
namespace internal { |
@@ -60,16 +61,21 @@ namespace internal { |
// amount of allocated memory (in case this forces a purge). When memory usage |
// reaches the limit, the manager purges the LRU memory. |
// |
-// When notified of memory pressure, the manager either purges the LRU memory -- |
-// if the pressure is moderate -- or all discardable memory if the pressure is |
-// critical. |
+// When notified of memory pressure, the manager either purges the LRU memory |
+// -- if the pressure is moderate -- or all discardable memory if the pressure |
+// is critical. |
+// |
+// When notified that idle, the manager purges memory not used since the hard |
+// memory limit cutoff. |
class BASE_EXPORT_PRIVATE DiscardableMemoryManager { |
public: |
typedef DiscardableMemoryManagerAllocation Allocation; |
DiscardableMemoryManager(size_t memory_limit, |
- size_t bytes_to_keep_under_moderate_pressure); |
- ~DiscardableMemoryManager(); |
+ size_t soft_memory_limit, |
+ size_t bytes_to_keep_under_moderate_pressure, |
+ TimeDelta hard_memory_limit_expiration_time); |
+ virtual ~DiscardableMemoryManager(); |
// Call this to register memory pressure listener. Must be called on a thread |
// with a MessageLoop current. |
@@ -79,13 +85,26 @@ class BASE_EXPORT_PRIVATE DiscardableMemoryManager { |
void UnregisterMemoryPressureListener(); |
// The maximum number of bytes of memory that may be allocated before we force |
- // a purge. If this amount is zero, it is interpreted as having no limit at |
- // all. |
+ // a purge. |
void SetMemoryLimit(size_t bytes); |
+ // The number of bytes of memory that may be allocated but unused for the hard |
+ // limit expiration time without getting purged. |
+ void SetSoftMemoryLimit(size_t bytes); |
+ |
// Sets the amount of memory to keep when we're under moderate pressure. |
void SetBytesToKeepUnderModeratePressure(size_t bytes); |
+ // Sets the memory usage cutoff time for hard memory limit. |
+ void SetHardMemoryLimitExpirationTime( |
+ TimeDelta hard_memory_limit_expiration_time); |
+ |
+ // Call this when idle. Reduces will attempt to reduce memory footprint |
+ // until within soft memory limit. |
+ // Returns true if there's no need to call this again until allocations |
+ // have been used. |
+ bool IdleNotification(); |
+ |
// Adds the given allocation to the manager's collection. |
void Register(Allocation* allocation, size_t bytes); |
@@ -116,12 +135,17 @@ class BASE_EXPORT_PRIVATE DiscardableMemoryManager { |
// used by tests. |
size_t GetBytesAllocatedForTest() const; |
+ protected: |
+ // Virtual for tests. |
+ virtual TimeTicks Now() const; |
+ |
private: |
struct AllocationInfo { |
explicit AllocationInfo(size_t bytes) : bytes(bytes), purgable(false) {} |
const size_t bytes; |
bool purgable; |
+ TimeTicks last_usage; |
}; |
typedef HashingMRUCache<Allocation*, AllocationInfo> AllocationMap; |
@@ -129,20 +153,25 @@ class BASE_EXPORT_PRIVATE DiscardableMemoryManager { |
void OnMemoryPressure( |
MemoryPressureListener::MemoryPressureLevel pressure_level); |
- // Purges memory until usage is within |
+ // Purges memory until usage is less or equal to |
// |bytes_to_keep_under_moderate_pressure_|. |
- void Purge(); |
+ void PurgeUntilWithinBytesToKeepUnderModeratePressure(); |
- // Purges least recently used memory until usage is less or equal to |limit|. |
- // Caller must acquire |lock_| prior to calling this function. |
- void PurgeLRUWithLockAcquiredUntilUsageIsWithin(size_t limit); |
+ // Purges memory not used since |hard_memory_limit_expiration_time_| before |
+ // "right now" until usage is less or equal to |soft_memory_limit_|. |
+ // Returns true if total amount of memory is less or equal to soft memory |
+ // limit. |
+ bool PurgeIfNotUsedSinceHardLimitCutoffUntilWithinSoftMemoryLimit(); |
- // Ensures that we don't allocate beyond our memory limit. Caller must acquire |
- // |lock_| prior to calling this function. |
- void EnforcePolicyWithLockAcquired(); |
+ // Purges memory that has not been used since |timestamp| until usage is less |
+ // or equal to |limit|. |
+ // Caller must acquire |lock_| prior to calling this function. |
+ void PurgeIfNotUsedSinceTimestampUntilUsageIsWithinLimitWithLockAcquired( |
+ TimeTicks timestamp, |
+ size_t limit); |
// Called when a change to |bytes_allocated_| has been made. |
- void BytesAllocatedChanged() const; |
+ void BytesAllocatedChanged(size_t new_bytes_allocated) const; |
// Needs to be held when accessing members. |
mutable Lock lock_; |
@@ -156,6 +185,10 @@ class BASE_EXPORT_PRIVATE DiscardableMemoryManager { |
// The maximum number of bytes of memory that may be allocated. |
size_t memory_limit_; |
+ // The number of bytes of memory that may be allocated but not used since |
+ // |hard_memory_limit_expiration_time_| before "right now". |
+ size_t soft_memory_limit_; |
+ |
// Under moderate memory pressure, we will purge memory until usage is within |
// this limit. |
size_t bytes_to_keep_under_moderate_pressure_; |
@@ -164,6 +197,10 @@ class BASE_EXPORT_PRIVATE DiscardableMemoryManager { |
// pressure. |
scoped_ptr<MemoryPressureListener> memory_pressure_listener_; |
+ // Amount of time it takes for an allocation to become affected by |
+ // |soft_memory_limit_|. |
+ TimeDelta hard_memory_limit_expiration_time_; |
+ |
DISALLOW_COPY_AND_ASSIGN(DiscardableMemoryManager); |
}; |