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

Unified Diff: base/memory/discardable_memory_manager.cc

Issue 336273003: base: Add soft memory limit to DiscardableMemoryManager. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix mac build Created 6 years, 5 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 | « base/memory/discardable_memory_manager.h ('k') | base/memory/discardable_memory_manager_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: base/memory/discardable_memory_manager.cc
diff --git a/base/memory/discardable_memory_manager.cc b/base/memory/discardable_memory_manager.cc
index 49ecc484a7a6ff195f4e5cb23316eaef4625a73f..d976da203c4a88494dfffa6e73dd167bee6c2c11 100644
--- a/base/memory/discardable_memory_manager.cc
+++ b/base/memory/discardable_memory_manager.cc
@@ -17,13 +17,17 @@ namespace internal {
DiscardableMemoryManager::DiscardableMemoryManager(
size_t memory_limit,
- size_t bytes_to_keep_under_moderate_pressure)
+ size_t soft_memory_limit,
+ size_t bytes_to_keep_under_moderate_pressure,
+ TimeDelta hard_memory_limit_expiration_time)
: allocations_(AllocationMap::NO_AUTO_EVICT),
- bytes_allocated_(0),
+ bytes_allocated_(0u),
memory_limit_(memory_limit),
+ soft_memory_limit_(soft_memory_limit),
bytes_to_keep_under_moderate_pressure_(
- bytes_to_keep_under_moderate_pressure) {
- BytesAllocatedChanged();
+ bytes_to_keep_under_moderate_pressure),
+ hard_memory_limit_expiration_time_(hard_memory_limit_expiration_time) {
+ BytesAllocatedChanged(bytes_allocated_);
}
DiscardableMemoryManager::~DiscardableMemoryManager() {
@@ -48,7 +52,13 @@ void DiscardableMemoryManager::UnregisterMemoryPressureListener() {
void DiscardableMemoryManager::SetMemoryLimit(size_t bytes) {
AutoLock lock(lock_);
memory_limit_ = bytes;
- EnforcePolicyWithLockAcquired();
+ PurgeIfNotUsedSinceTimestampUntilUsageIsWithinLimitWithLockAcquired(
+ Now(), memory_limit_);
+}
+
+void DiscardableMemoryManager::SetSoftMemoryLimit(size_t bytes) {
+ AutoLock lock(lock_);
+ soft_memory_limit_ = bytes;
}
void DiscardableMemoryManager::SetBytesToKeepUnderModeratePressure(
@@ -57,6 +67,16 @@ void DiscardableMemoryManager::SetBytesToKeepUnderModeratePressure(
bytes_to_keep_under_moderate_pressure_ = bytes;
}
+void DiscardableMemoryManager::SetHardMemoryLimitExpirationTime(
+ TimeDelta hard_memory_limit_expiration_time) {
+ AutoLock lock(lock_);
+ hard_memory_limit_expiration_time_ = hard_memory_limit_expiration_time;
+}
+
+bool DiscardableMemoryManager::ReduceMemoryUsage() {
+ return PurgeIfNotUsedSinceHardLimitCutoffUntilWithinSoftMemoryLimit();
+}
+
void DiscardableMemoryManager::Register(Allocation* allocation, size_t bytes) {
AutoLock lock(lock_);
// A registered memory listener is currently required. This DCHECK can be
@@ -78,7 +98,7 @@ void DiscardableMemoryManager::Unregister(Allocation* allocation) {
size_t bytes_purgable = info.bytes;
DCHECK_LE(bytes_purgable, bytes_allocated_);
bytes_allocated_ -= bytes_purgable;
- BytesAllocatedChanged();
+ BytesAllocatedChanged(bytes_allocated_);
}
allocations_.Erase(it);
}
@@ -95,6 +115,7 @@ bool DiscardableMemoryManager::AcquireLock(Allocation* allocation,
if (!info->bytes)
return false;
+ TimeTicks now = Now();
size_t bytes_required = info->purgable ? 0u : info->bytes;
if (memory_limit_) {
@@ -102,7 +123,8 @@ bool DiscardableMemoryManager::AcquireLock(Allocation* allocation,
if (bytes_required < memory_limit_)
limit = memory_limit_ - bytes_required;
- PurgeLRUWithLockAcquiredUntilUsageIsWithin(limit);
+ PurgeIfNotUsedSinceTimestampUntilUsageIsWithinLimitWithLockAcquired(now,
+ limit);
}
// Check for overflow.
@@ -111,9 +133,10 @@ bool DiscardableMemoryManager::AcquireLock(Allocation* allocation,
*purged = !allocation->AllocateAndAcquireLock();
info->purgable = false;
+ info->last_usage = now;
if (bytes_required) {
bytes_allocated_ += bytes_required;
- BytesAllocatedChanged();
+ BytesAllocatedChanged(bytes_allocated_);
}
return true;
}
@@ -126,14 +149,18 @@ void DiscardableMemoryManager::ReleaseLock(Allocation* allocation) {
DCHECK(it != allocations_.end());
AllocationInfo* info = &it->second;
+ TimeTicks now = Now();
allocation->ReleaseLock();
info->purgable = true;
- EnforcePolicyWithLockAcquired();
+ info->last_usage = now;
+
+ PurgeIfNotUsedSinceTimestampUntilUsageIsWithinLimitWithLockAcquired(
+ now, memory_limit_);
}
void DiscardableMemoryManager::PurgeAll() {
AutoLock lock(lock_);
- PurgeLRUWithLockAcquiredUntilUsageIsWithin(0);
+ PurgeIfNotUsedSinceTimestampUntilUsageIsWithinLimitWithLockAcquired(Now(), 0);
}
bool DiscardableMemoryManager::IsRegisteredForTest(
@@ -159,7 +186,7 @@ void DiscardableMemoryManager::OnMemoryPressure(
MemoryPressureListener::MemoryPressureLevel pressure_level) {
switch (pressure_level) {
case MemoryPressureListener::MEMORY_PRESSURE_MODERATE:
- Purge();
+ PurgeUntilWithinBytesToKeepUnderModeratePressure();
return;
case MemoryPressureListener::MEMORY_PRESSURE_CRITICAL:
PurgeAll();
@@ -169,21 +196,28 @@ void DiscardableMemoryManager::OnMemoryPressure(
NOTREACHED();
}
-void DiscardableMemoryManager::Purge() {
+void
+DiscardableMemoryManager::PurgeUntilWithinBytesToKeepUnderModeratePressure() {
AutoLock lock(lock_);
- PurgeLRUWithLockAcquiredUntilUsageIsWithin(
- bytes_to_keep_under_moderate_pressure_);
+ PurgeIfNotUsedSinceTimestampUntilUsageIsWithinLimitWithLockAcquired(
+ Now(), bytes_to_keep_under_moderate_pressure_);
}
-void DiscardableMemoryManager::PurgeLRUWithLockAcquiredUntilUsageIsWithin(
- size_t limit) {
- TRACE_EVENT1(
- "base",
- "DiscardableMemoryManager::PurgeLRUWithLockAcquiredUntilUsageIsWithin",
- "limit",
- limit);
+bool DiscardableMemoryManager::
+ PurgeIfNotUsedSinceHardLimitCutoffUntilWithinSoftMemoryLimit() {
+ AutoLock lock(lock_);
+
+ PurgeIfNotUsedSinceTimestampUntilUsageIsWithinLimitWithLockAcquired(
+ Now() - hard_memory_limit_expiration_time_, soft_memory_limit_);
+ return bytes_allocated_ <= soft_memory_limit_;
+}
+
+void DiscardableMemoryManager::
+ PurgeIfNotUsedSinceTimestampUntilUsageIsWithinLimitWithLockAcquired(
+ TimeTicks timestamp,
+ size_t limit) {
lock_.AssertAcquired();
size_t bytes_allocated_before_purging = bytes_allocated_;
@@ -195,7 +229,9 @@ void DiscardableMemoryManager::PurgeLRUWithLockAcquiredUntilUsageIsWithin(
if (bytes_allocated_ <= limit)
break;
- if (!info->purgable)
+
+ bool purgable = info->purgable && info->last_usage <= timestamp;
+ if (!purgable)
continue;
size_t bytes_purgable = info->bytes;
@@ -206,19 +242,21 @@ void DiscardableMemoryManager::PurgeLRUWithLockAcquiredUntilUsageIsWithin(
}
if (bytes_allocated_ != bytes_allocated_before_purging)
- BytesAllocatedChanged();
+ BytesAllocatedChanged(bytes_allocated_);
}
-void DiscardableMemoryManager::EnforcePolicyWithLockAcquired() {
- PurgeLRUWithLockAcquiredUntilUsageIsWithin(memory_limit_);
-}
-
-void DiscardableMemoryManager::BytesAllocatedChanged() const {
- TRACE_COUNTER_ID1("base", "DiscardableMemoryUsage", this, bytes_allocated_);
+void DiscardableMemoryManager::BytesAllocatedChanged(
+ size_t new_bytes_allocated) const {
+ TRACE_COUNTER_ID1(
+ "base", "DiscardableMemoryUsage", this, new_bytes_allocated);
static const char kDiscardableMemoryUsageKey[] = "dm-usage";
base::debug::SetCrashKeyValue(kDiscardableMemoryUsageKey,
- Uint64ToString(bytes_allocated_));
+ Uint64ToString(new_bytes_allocated));
+}
+
+TimeTicks DiscardableMemoryManager::Now() const {
+ return TimeTicks::Now();
}
} // namespace internal
« no previous file with comments | « base/memory/discardable_memory_manager.h ('k') | base/memory/discardable_memory_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698