0

base: Avoid purging more discardable memory than necessary.

In situations when discardable memory usage is above the limit,
instead of purging the amount of memory that we would try to
reclaim under moderate memory pressure, purge only what is
necessary to stay below the limit.

This simplifies the code and makes it easier to understand how
memory is purged as a result of reaching the memory limit.

BUG=237681
TEST=base_unittests --gtest_filter=DiscardableMemoryProviderPermutationTests/DiscardableMemoryProviderPermutationTest.LRUDiscardedAmount/*

Review URL: https://codereview.chromium.org/59083011

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@234652 0039d316-1c4b-4281-b951-d872f2087c98
This commit is contained in:
reveman@chromium.org
2013-11-12 22:43:23 +00:00
parent 337602e45f
commit bc5bb33c7c
3 changed files with 22 additions and 17 deletions

@ -86,7 +86,6 @@ void DiscardableMemoryProvider::SetBytesToReclaimUnderModeratePressure(
size_t bytes) {
AutoLock lock(lock_);
bytes_to_reclaim_under_moderate_pressure_ = bytes;
EnforcePolicyWithLockAcquired();
}
void DiscardableMemoryProvider::Register(
@ -191,7 +190,7 @@ void DiscardableMemoryProvider::Purge() {
return;
size_t limit = 0;
if (bytes_to_reclaim_under_moderate_pressure_ < discardable_memory_limit_)
if (bytes_to_reclaim_under_moderate_pressure_ < bytes_allocated_)
limit = bytes_allocated_ - bytes_to_reclaim_under_moderate_pressure_;
PurgeLRUWithLockAcquiredUntilUsageIsWithin(limit);
@ -223,17 +222,7 @@ void DiscardableMemoryProvider::PurgeLRUWithLockAcquiredUntilUsageIsWithin(
}
void DiscardableMemoryProvider::EnforcePolicyWithLockAcquired() {
lock_.AssertAcquired();
bool exceeded_bound = bytes_allocated_ > discardable_memory_limit_;
if (!exceeded_bound || !bytes_to_reclaim_under_moderate_pressure_)
return;
size_t limit = 0;
if (bytes_to_reclaim_under_moderate_pressure_ < discardable_memory_limit_)
limit = bytes_allocated_ - bytes_to_reclaim_under_moderate_pressure_;
PurgeLRUWithLockAcquiredUntilUsageIsWithin(limit);
PurgeLRUWithLockAcquiredUntilUsageIsWithin(discardable_memory_limit_);
}
} // namespace internal

@ -55,8 +55,8 @@ class BASE_EXPORT_PRIVATE DiscardableMemoryProvider {
static void SetInstanceForTest(DiscardableMemoryProvider* provider);
// The maximum number of bytes of discardable memory that may be allocated
// before we assume moderate memory pressure. If this amount is zero, it is
// interpreted as having no limit at all.
// before we force a purge. If this amount is zero, it is interpreted as
// having no limit at all.
void SetDiscardableMemoryLimit(size_t bytes);
// Sets the amount of memory to reclaim when we're under moderate pressure.
@ -110,8 +110,8 @@ class BASE_EXPORT_PRIVATE DiscardableMemoryProvider {
static void NotifyMemoryPressure(
MemoryPressureListener::MemoryPressureLevel pressure_level);
// Purges least recently used memory based on the value of
// |bytes_to_reclaim_under_moderate_pressure_|.
// Purges |bytes_to_reclaim_under_moderate_pressure_| bytes of
// discardable memory.
void Purge();
// Purges least recently used memory until usage is less or equal to |limit|.

@ -232,6 +232,22 @@ TEST_P(DiscardableMemoryProviderPermutationTest, LRUDiscardedExceedLimit) {
EXPECT_NE(static_cast<void*>(NULL), Memory(discardable(0)));
}
// Verify that no more memory than necessary was discarded after changing
// memory limit.
TEST_P(DiscardableMemoryProviderPermutationTest, LRUDiscardedAmount) {
SetBytesToReclaimUnderModeratePressure(2048);
SetDiscardableMemoryLimit(4096);
CreateAndUseDiscardableMemory();
SetDiscardableMemoryLimit(2048);
EXPECT_EQ(DISCARDABLE_MEMORY_SUCCESS, discardable(2)->Lock());
EXPECT_EQ(DISCARDABLE_MEMORY_PURGED, discardable(1)->Lock());
// 0 should still be locked.
EXPECT_NE(static_cast<void*>(NULL), Memory(discardable(0)));
}
TEST_P(DiscardableMemoryProviderPermutationTest,
CriticalPressureFreesAllUnlocked) {
CreateAndUseDiscardableMemory();