| Index: content/browser/dom_storage/dom_storage_context_impl.cc
|
| diff --git a/content/browser/dom_storage/dom_storage_context_impl.cc b/content/browser/dom_storage/dom_storage_context_impl.cc
|
| index 1e6afa770e521e38a77f85825d066a4760759e4e..9f121cdf9f413dbd348a2010669cc946f002e5e0 100644
|
| --- a/content/browser/dom_storage/dom_storage_context_impl.cc
|
| +++ b/content/browser/dom_storage/dom_storage_context_impl.cc
|
| @@ -13,6 +13,8 @@
|
| #include "base/files/file_util.h"
|
| #include "base/guid.h"
|
| #include "base/location.h"
|
| +#include "base/metrics/histogram.h"
|
| +#include "base/sys_info.h"
|
| #include "base/time/time.h"
|
| #include "base/trace_event/memory_dump_manager.h"
|
| #include "base/trace_event/process_memory_dump.h"
|
| @@ -28,12 +30,39 @@
|
| #include "storage/browser/quota/special_storage_policy.h"
|
|
|
| namespace content {
|
| +namespace {
|
|
|
| -static const int kSessionStoraceScavengingSeconds = 60;
|
| +// Limits on the cache size and number of areas in memory, over which the areas
|
| +// are purged.
|
| +#if defined(OS_ANDROID)
|
| +const unsigned kMaxStorageAreaCount = 20;
|
| +const size_t kMaxCacheSize = 2 * 1024 * 1024;
|
| +#else
|
| +const unsigned kMaxStorageAreaCount = 100;
|
| +const size_t kMaxCacheSize = 20 * 1024 * 1024;
|
| +#endif
|
| +
|
| +const int kSessionStoraceScavengingSeconds = 60;
|
|
|
| // Offset the session storage namespace ids generated by different contexts
|
| // to help identify when an id from one is mistakenly used in another.
|
| -static int g_session_id_offset_sequence = 1;
|
| +int g_session_id_offset_sequence = 1;
|
| +
|
| +// Aggregates statistics from all the namespaces.
|
| +DOMStorageNamespace::UsageStatistics GetTotalNamespaceStatistics(
|
| + const DOMStorageContextImpl::StorageNamespaceMap& namespace_map) {
|
| + DOMStorageNamespace::UsageStatistics total_stats = {0};
|
| + for (const auto& it : namespace_map) {
|
| + DOMStorageNamespace::UsageStatistics stats =
|
| + it.second->GetUsageStatistics();
|
| + total_stats.total_cache_size += stats.total_cache_size;
|
| + total_stats.total_area_count += stats.total_area_count;
|
| + total_stats.inactive_area_count += stats.inactive_area_count;
|
| + }
|
| + return total_stats;
|
| +}
|
| +
|
| +} // namespace
|
|
|
| DOMStorageContextImpl::DOMStorageContextImpl(
|
| const base::FilePath& localstorage_directory,
|
| @@ -47,7 +76,8 @@ DOMStorageContextImpl::DOMStorageContextImpl(
|
| is_shutdown_(false),
|
| force_keep_session_state_(false),
|
| special_storage_policy_(special_storage_policy),
|
| - scavenging_started_(false) {
|
| + scavenging_started_(false),
|
| + is_low_end_device_(base::SysInfo::IsLowEndDevice()) {
|
| // AtomicSequenceNum starts at 0 but we want to start session
|
| // namespace ids at one since zero is reserved for the
|
| // kLocalStorageNamespaceId.
|
| @@ -396,6 +426,45 @@ void DOMStorageContextImpl::StartScavengingUnusedSessionStorage() {
|
| }
|
| }
|
|
|
| +void DOMStorageContextImpl::PurgeMemory(PurgeOption purge_option) {
|
| + if (is_shutdown_)
|
| + return;
|
| +
|
| + DOMStorageNamespace::UsageStatistics initial_stats =
|
| + GetTotalNamespaceStatistics(namespaces_);
|
| +
|
| + // Track the total localStorage cache size.
|
| + UMA_HISTOGRAM_CUSTOM_COUNTS("LocalStorage.BrowserLocalStorageCacheSizeInKB",
|
| + initial_stats.total_cache_size / 1024, 1, 100000,
|
| + 50);
|
| +
|
| + if (purge_option == PURGE_IF_NEEDED) {
|
| + // Purging is done based on the cache sizes without including the database
|
| + // size since it can be expensive trying to estimate the sqlite usage for
|
| + // all databases. For low end devices purge all inactive areas.
|
| + bool should_purge =
|
| + (is_low_end_device_ && initial_stats.inactive_area_count) ||
|
| + initial_stats.total_cache_size > kMaxCacheSize ||
|
| + initial_stats.total_area_count > kMaxStorageAreaCount;
|
| + if (!should_purge)
|
| + return;
|
| +
|
| + purge_option = PURGE_UNOPENED;
|
| + }
|
| +
|
| + bool aggressively = purge_option == PURGE_AGGRESSIVE;
|
| + for (const auto& it : namespaces_)
|
| + it.second->PurgeMemory(aggressively);
|
| +
|
| + // Track the size of cache purged.
|
| + UMA_HISTOGRAM_CUSTOM_COUNTS(
|
| + "LocalStorage.BrowserLocalStorageCachePurgedInKB",
|
| + (initial_stats.total_cache_size -
|
| + GetTotalNamespaceStatistics(namespaces_).total_cache_size) /
|
| + 1024,
|
| + 1, 100000, 50);
|
| +}
|
| +
|
| bool DOMStorageContextImpl::OnMemoryDump(
|
| const base::trace_event::MemoryDumpArgs& args,
|
| base::trace_event::ProcessMemoryDump* pmd) {
|
|
|