Commit 1c884a79 authored by Maks Orlovich's avatar Maks Orlovich Committed by Commit Bot

Drop incognito profiles in-memory browser cache when memory gets low.

... It's not going to keep much cached if the process gets OOM killed,
after all.

Bug: 845639
Change-Id: Ic3e8ac616e2b511f995410a5aa54c1342cef0b63
Reviewed-on: https://chromium-review.googlesource.com/1110155
Commit-Queue: Maks Orlovich <morlovich@chromium.org>
Reviewed-by: default avatarJosh Karlin <jkarlin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#580933}
parent 5491b007
......@@ -7,6 +7,7 @@
#include "base/bind_helpers.h"
#include "base/files/file.h"
#include "base/files/file_util.h"
#include "base/memory/memory_pressure_listener.h"
#include "base/metrics/field_trial.h"
#include "base/run_loop.h"
#include "base/sequenced_task_runner.h"
......@@ -743,6 +744,39 @@ TEST_F(DiskCacheBackendTest, BlockFileCacheMemoryDump) {
EXPECT_EQ(1u, pmd.allocator_dumps().size());
}
TEST_F(DiskCacheBackendTest, MemoryListensToMemoryPressure) {
const int kLimit = 16 * 1024;
const int kEntrySize = 256;
SetMaxSize(kLimit);
SetMemoryOnlyMode();
InitCache();
// Fill in to about 80-90% full.
scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kEntrySize));
CacheTestFillBuffer(buffer->data(), kEntrySize, false);
for (int i = 0; i < 0.9 * (kLimit / kEntrySize); ++i) {
disk_cache::Entry* entry = nullptr;
ASSERT_EQ(net::OK, CreateEntry(base::IntToString(i), &entry));
EXPECT_EQ(kEntrySize,
WriteData(entry, 0, 0, buffer.get(), kEntrySize, true));
entry->Close();
}
EXPECT_GT(CalculateSizeOfAllEntries(), 0.8 * kLimit);
// Signal low-memory of various sorts, and see how small it gets.
base::MemoryPressureListener::NotifyMemoryPressure(
base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE);
base::RunLoop().RunUntilIdle();
EXPECT_LT(CalculateSizeOfAllEntries(), 0.5 * kLimit);
base::MemoryPressureListener::NotifyMemoryPressure(
base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
base::RunLoop().RunUntilIdle();
EXPECT_LT(CalculateSizeOfAllEntries(), 0.1 * kLimit);
}
TEST_F(DiskCacheBackendTest, ExternalFiles) {
InitCache();
// First, let's create a file on the folder.
......
......@@ -56,8 +56,13 @@ base::LinkNode<MemEntryImpl>* NextSkippingChildren(
} // namespace
MemBackendImpl::MemBackendImpl(net::NetLog* net_log)
: max_size_(0), current_size_(0), net_log_(net_log), weak_factory_(this) {
}
: max_size_(0),
current_size_(0),
net_log_(net_log),
memory_pressure_listener_(
base::BindRepeating(&MemBackendImpl::OnMemoryPressure,
base::Unretained(this))),
weak_factory_(this) {}
MemBackendImpl::~MemBackendImpl() {
DCHECK(CheckLRUListOrder(lru_list_));
......@@ -341,9 +346,11 @@ size_t MemBackendImpl::DumpMemoryStats(
void MemBackendImpl::EvictIfNeeded() {
if (current_size_ <= max_size_)
return;
int target_size = std::max(0, max_size_ - kDefaultEvictionSize);
EvictTill(target_size);
}
void MemBackendImpl::EvictTill(int target_size) {
base::LinkNode<MemEntryImpl>* entry = lru_list_.head();
while (current_size_ > target_size && entry != lru_list_.end()) {
MemEntryImpl* to_doom = entry->value();
......@@ -354,4 +361,20 @@ void MemBackendImpl::EvictIfNeeded() {
}
}
void MemBackendImpl::OnMemoryPressure(
base::MemoryPressureListener::MemoryPressureLevel memory_pressure_level) {
switch (memory_pressure_level) {
case base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE:
// Not supposed to get this here, but if there is no problem, there is
// no problem...
break;
case base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE:
EvictTill(max_size_ / 2);
break;
case base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL:
EvictTill(max_size_ / 10);
break;
}
}
} // namespace disk_cache
......@@ -16,6 +16,7 @@
#include "base/compiler_specific.h"
#include "base/containers/linked_list.h"
#include "base/macros.h"
#include "base/memory/memory_pressure_listener.h"
#include "base/memory/weak_ptr.h"
#include "base/strings/string_split.h"
#include "base/time/time.h"
......@@ -122,6 +123,13 @@ class NET_EXPORT_PRIVATE MemBackendImpl final : public Backend {
// Deletes entries from the cache until the current size is below the limit.
void EvictIfNeeded();
// Deletes entries until the current size is below |goal|.
void EvictTill(int target_size);
// Called when we get low on memory.
void OnMemoryPressure(
base::MemoryPressureListener::MemoryPressureLevel memory_pressure_level);
EntryMap entries_;
// Stored in increasing order of last use time, from least recently used to
......@@ -134,6 +142,8 @@ class NET_EXPORT_PRIVATE MemBackendImpl final : public Backend {
net::NetLog* net_log_;
base::OnceClosure post_cleanup_callback_;
base::MemoryPressureListener memory_pressure_listener_;
base::WeakPtrFactory<MemBackendImpl> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(MemBackendImpl);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment