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

Unified Diff: content/browser/dom_storage/dom_storage_namespace.cc

Issue 1953703004: Purge browser cache for dom storage in a smarter way (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@dom_storage
Patch Set: Created 4 years, 7 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
Index: content/browser/dom_storage/dom_storage_namespace.cc
diff --git a/content/browser/dom_storage/dom_storage_namespace.cc b/content/browser/dom_storage/dom_storage_namespace.cc
index 72fae88fcedd3743a0f2d1707a6aa4a3f087975f..6ba3f6b0f87cdaaad00b7e9aeea82e105a02b440 100644
--- a/content/browser/dom_storage/dom_storage_namespace.cc
+++ b/content/browser/dom_storage/dom_storage_namespace.cc
@@ -4,9 +4,12 @@
#include "content/browser/dom_storage/dom_storage_namespace.h"
+#include <algorithm>
+
#include "base/bind.h"
#include "base/location.h"
#include "base/logging.h"
+#include "base/sys_info.h"
#include "content/browser/dom_storage/dom_storage_area.h"
#include "content/browser/dom_storage/dom_storage_task_runner.h"
#include "content/browser/dom_storage/session_storage_database.h"
@@ -30,7 +33,8 @@ DOMStorageNamespace::DOMStorageNamespace(
: namespace_id_(namespace_id),
persistent_namespace_id_(persistent_namespace_id),
task_runner_(task_runner),
- session_storage_database_(session_storage_database) {
+ session_storage_database_(session_storage_database),
+ is_low_end_device_(base::SysInfo::IsLowEndDevice()) {
DCHECK_NE(kLocalStorageNamespaceId, namespace_id);
}
@@ -120,6 +124,11 @@ void DOMStorageNamespace::DeleteSessionStorageOrigin(const GURL& origin) {
void DOMStorageNamespace::PurgeMemory(PurgeOption option) {
if (directory_.empty())
return; // We can't purge w/o backing on disk.
+
+ option = std::max(option, FindPurgeLevel());
+ if (option == PURGE_UNSPECIFIED)
+ return;
+
AreaMap::iterator it = areas_.begin();
while (it != areas_.end()) {
const AreaHolder& holder = it->second;
@@ -131,7 +140,10 @@ void DOMStorageNamespace::PurgeMemory(PurgeOption option) {
// we can drop it from memory.
holder.area_->ScheduleImmediateCommit();
}
- ++it;
+
+ if (option == PURGE_AGGRESSIVE)
+ holder.area_->TrimDatabase();
+ it++;
continue;
}
@@ -148,9 +160,63 @@ void DOMStorageNamespace::PurgeMemory(PurgeOption option) {
// for opened areas.
holder.area_->PurgeMemory();
}
+ it++;
+ }
+}
+
+// This function works based on the cache sizes without including the database
+// size since it can be expensive trying to estimate the sqlite usage for all
+// databases.
+DOMStorageNamespace::PurgeOption DOMStorageNamespace::FindPurgeLevel() {
+ // Maximum in-memory cache usage of all databases.
+ size_t in_memory_areas_size_budget = 20 * 1024 * 1024;
+ // Maximum in-memory cache usage of databases that are open.
+ size_t inactive_in_memory_area_size_budget = 20 * 1024 * 1024;
+ // Number of areas over which the open databases can be purged.
+ size_t active_in_memory_areas_unpurged = 100;
+#if defined(OS_ANDROID)
michaeln 2016/05/09 22:12:17 This might be more complicated then it needs to be
ssid 2016/05/10 02:04:16 I agree this is very complicated. I was expecting
+ if (is_low_end_device_) {
+ // For low-end devices, when the cache size reaches 5Mib, only 10 open
+ // databases are allowed before being purged.
+ active_in_memory_areas_unpurged = 10;
+ in_memory_areas_size_budget = 5 * 1024 * 1024;
+ // Clear most of the inactive database on low-end device.
+ inactive_in_memory_area_size_budget = 100 * 1024;
+ } else {
+ // Set a low cache budget for inactive database cache on android.
+ inactive_in_memory_area_size_budget = 1024 * 1024;
ssid 2016/05/06 03:28:51 I chose these values based on what sizes I observe
michaeln 2016/05/09 22:12:17 we don't have stats for the number of 'area in use
+ }
+#endif
+
+ size_t total_cache_size = 0;
+ size_t area_count = 0;
+ size_t active_areas_cache_size = 0;
+ unsigned active_areas_count = 0;
+ for (AreaMap::const_iterator it = areas_.begin(); it != areas_.end(); ++it) {
+ if (it->second.area_->IsLoadedInMemory()) {
+ size_t cache_size = it->second.area_->map_usage_in_bytes();
ssid 2016/05/06 03:28:52 Do you think just the cache size is a good estimat
michaeln 2016/05/09 22:12:17 Sure, this is what we have to work with.
+ total_cache_size += cache_size;
+ ++area_count;
+ if (it->second.open_count_ > 0) {
+ active_areas_cache_size += cache_size;
+ ++active_areas_count;
+ }
+ }
+ }
+
+ if (active_areas_cache_size > in_memory_areas_size_budget &&
+ active_areas_count > active_in_memory_areas_unpurged) {
+ return PURGE_AGGRESSIVE;
+ }
- ++it;
+ size_t purgeable_cache_size = total_cache_size - active_areas_cache_size;
+ if (purgeable_cache_size) {
+ if (purgeable_cache_size > inactive_in_memory_area_size_budget ||
+ total_cache_size > in_memory_areas_size_budget) {
+ return PURGE_UNOPENED;
+ }
}
+ return PURGE_UNSPECIFIED;
}
void DOMStorageNamespace::Shutdown() {
@@ -167,15 +233,6 @@ void DOMStorageNamespace::Flush() {
}
}
-unsigned int DOMStorageNamespace::CountInMemoryAreas() const {
- unsigned int area_count = 0;
- for (AreaMap::const_iterator it = areas_.begin(); it != areas_.end(); ++it) {
- if (it->second.area_->IsLoadedInMemory())
- ++area_count;
- }
- return area_count;
-}
-
void DOMStorageNamespace::OnMemoryDump(
base::trace_event::ProcessMemoryDump* pmd) {
DCHECK(task_runner_->IsRunningOnPrimarySequence());

Powered by Google App Engine
This is Rietveld 408576698