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

Side by Side Diff: content/browser/dom_storage/dom_storage_context_impl.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: Add content_export. 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 unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/dom_storage/dom_storage_context_impl.h" 5 #include "content/browser/dom_storage/dom_storage_context_impl.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 #include <stdlib.h> 8 #include <stdlib.h>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
11 #include "base/bind_helpers.h" 11 #include "base/bind_helpers.h"
12 #include "base/files/file_enumerator.h" 12 #include "base/files/file_enumerator.h"
13 #include "base/files/file_util.h" 13 #include "base/files/file_util.h"
14 #include "base/guid.h" 14 #include "base/guid.h"
15 #include "base/location.h" 15 #include "base/location.h"
16 #include "base/metrics/histogram.h"
17 #include "base/sys_info.h"
16 #include "base/time/time.h" 18 #include "base/time/time.h"
17 #include "base/trace_event/memory_dump_manager.h" 19 #include "base/trace_event/memory_dump_manager.h"
18 #include "base/trace_event/process_memory_dump.h" 20 #include "base/trace_event/process_memory_dump.h"
19 #include "content/browser/dom_storage/dom_storage_area.h" 21 #include "content/browser/dom_storage/dom_storage_area.h"
20 #include "content/browser/dom_storage/dom_storage_database.h" 22 #include "content/browser/dom_storage/dom_storage_database.h"
21 #include "content/browser/dom_storage/dom_storage_namespace.h" 23 #include "content/browser/dom_storage/dom_storage_namespace.h"
22 #include "content/browser/dom_storage/dom_storage_task_runner.h" 24 #include "content/browser/dom_storage/dom_storage_task_runner.h"
23 #include "content/browser/dom_storage/session_storage_database.h" 25 #include "content/browser/dom_storage/session_storage_database.h"
24 #include "content/common/dom_storage/dom_storage_types.h" 26 #include "content/common/dom_storage/dom_storage_types.h"
25 #include "content/public/browser/dom_storage_context.h" 27 #include "content/public/browser/dom_storage_context.h"
26 #include "content/public/browser/local_storage_usage_info.h" 28 #include "content/public/browser/local_storage_usage_info.h"
27 #include "content/public/browser/session_storage_usage_info.h" 29 #include "content/public/browser/session_storage_usage_info.h"
28 #include "storage/browser/quota/special_storage_policy.h" 30 #include "storage/browser/quota/special_storage_policy.h"
29 31
30 namespace content { 32 namespace content {
33 namespace {
31 34
32 static const int kSessionStoraceScavengingSeconds = 60; 35 // Limits on the cache size and number of areas in memory, over which the areas
36 // are purged.
37 #if defined(OS_ANDROID)
38 const unsigned kMaxStorageAreaCount = 20;
39 const size_t kMaxCacheSize = 2 * 1024 * 1024;
40 #else
41 const unsigned kMaxStorageAreaCount = 100;
42 const size_t kMaxCacheSize = 20 * 1024 * 1024;
43 #endif
44
45 const int kSessionStoraceScavengingSeconds = 60;
33 46
34 // Offset the session storage namespace ids generated by different contexts 47 // Offset the session storage namespace ids generated by different contexts
35 // to help identify when an id from one is mistakenly used in another. 48 // to help identify when an id from one is mistakenly used in another.
36 static int g_session_id_offset_sequence = 1; 49 int g_session_id_offset_sequence = 1;
50
51 // Aggregates statistics from all the namespaces.
52 DOMStorageNamespace::UsageStatistics GetTotalNamespaceStatistics(
53 const DOMStorageContextImpl::StorageNamespaceMap& namespace_map) {
54 DOMStorageNamespace::UsageStatistics total_stats = {0};
55 for (const auto& it : namespace_map) {
56 DOMStorageNamespace::UsageStatistics stats =
57 it.second->GetUsageStatistics();
58 total_stats.total_cache_size += stats.total_cache_size;
59 total_stats.total_area_count += stats.total_area_count;
60 total_stats.inactive_area_count += stats.inactive_area_count;
61 }
62 return total_stats;
63 }
64
65 } // namespace
37 66
38 DOMStorageContextImpl::DOMStorageContextImpl( 67 DOMStorageContextImpl::DOMStorageContextImpl(
39 const base::FilePath& localstorage_directory, 68 const base::FilePath& localstorage_directory,
40 const base::FilePath& sessionstorage_directory, 69 const base::FilePath& sessionstorage_directory,
41 storage::SpecialStoragePolicy* special_storage_policy, 70 storage::SpecialStoragePolicy* special_storage_policy,
42 DOMStorageTaskRunner* task_runner) 71 DOMStorageTaskRunner* task_runner)
43 : localstorage_directory_(localstorage_directory), 72 : localstorage_directory_(localstorage_directory),
44 sessionstorage_directory_(sessionstorage_directory), 73 sessionstorage_directory_(sessionstorage_directory),
45 task_runner_(task_runner), 74 task_runner_(task_runner),
46 session_id_offset_(abs((g_session_id_offset_sequence++ % 10)) * 1000), 75 session_id_offset_(abs((g_session_id_offset_sequence++ % 10)) * 1000),
47 is_shutdown_(false), 76 is_shutdown_(false),
48 force_keep_session_state_(false), 77 force_keep_session_state_(false),
49 special_storage_policy_(special_storage_policy), 78 special_storage_policy_(special_storage_policy),
50 scavenging_started_(false) { 79 scavenging_started_(false),
80 is_low_end_device_(base::SysInfo::IsLowEndDevice()) {
51 // AtomicSequenceNum starts at 0 but we want to start session 81 // AtomicSequenceNum starts at 0 but we want to start session
52 // namespace ids at one since zero is reserved for the 82 // namespace ids at one since zero is reserved for the
53 // kLocalStorageNamespaceId. 83 // kLocalStorageNamespaceId.
54 session_id_sequence_.GetNext(); 84 session_id_sequence_.GetNext();
55 85
56 // Tests may run without task runners. 86 // Tests may run without task runners.
57 if (task_runner_) { 87 if (task_runner_) {
58 // Registering dump provider is safe even outside the task runner. 88 // Registering dump provider is safe even outside the task runner.
59 base::trace_event::MemoryDumpManager::GetInstance() 89 base::trace_event::MemoryDumpManager::GetInstance()
60 ->RegisterDumpProviderWithSequencedTaskRunner( 90 ->RegisterDumpProviderWithSequencedTaskRunner(
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after
389 419
390 void DOMStorageContextImpl::StartScavengingUnusedSessionStorage() { 420 void DOMStorageContextImpl::StartScavengingUnusedSessionStorage() {
391 if (session_storage_database_.get()) { 421 if (session_storage_database_.get()) {
392 task_runner_->PostDelayedTask( 422 task_runner_->PostDelayedTask(
393 FROM_HERE, base::Bind(&DOMStorageContextImpl::FindUnusedNamespaces, 423 FROM_HERE, base::Bind(&DOMStorageContextImpl::FindUnusedNamespaces,
394 this), 424 this),
395 base::TimeDelta::FromSeconds(kSessionStoraceScavengingSeconds)); 425 base::TimeDelta::FromSeconds(kSessionStoraceScavengingSeconds));
396 } 426 }
397 } 427 }
398 428
429 void DOMStorageContextImpl::PurgeMemory(PurgeOption purge_option) {
430 if (is_shutdown_)
431 return;
432
433 DOMStorageNamespace::UsageStatistics initial_stats =
434 GetTotalNamespaceStatistics(namespaces_);
435
436 // Track the total localStorage cache size.
437 UMA_HISTOGRAM_CUSTOM_COUNTS("LocalStorage.BrowserLocalStorageCacheSizeInKB",
438 initial_stats.total_cache_size / 1024, 0, 100000,
Mark P 2016/05/23 18:27:14 There is already an "underflow" bucket; please use
ssid 2016/05/23 18:42:17 Done.
439 50);
440
441 if (purge_option == PURGE_IF_NEEDED) {
442 // Purging is done based on the cache sizes without including the database
443 // size since it can be expensive trying to estimate the sqlite usage for
444 // all databases. For low end devices purge all inactive areas.
445 bool should_purge =
446 (is_low_end_device_ && initial_stats.inactive_area_count) ||
447 initial_stats.total_cache_size > kMaxCacheSize ||
448 initial_stats.total_area_count > kMaxStorageAreaCount;
449 if (!should_purge)
450 return;
451
452 purge_option = PURGE_UNOPENED;
453 }
454
455 bool aggressively = purge_option == PURGE_AGGRESSIVE;
456 for (const auto& it : namespaces_)
457 it.second->PurgeMemory(aggressively);
458
459 // Track the size of cache purged.
460 UMA_HISTOGRAM_CUSTOM_COUNTS(
461 "LocalStorage.BrowserLocalStorageCachePurgedInKB",
462 (initial_stats.total_cache_size -
463 GetTotalNamespaceStatistics(namespaces_).total_cache_size) /
464 1024,
465 0, 100000, 50);
466 }
467
399 bool DOMStorageContextImpl::OnMemoryDump( 468 bool DOMStorageContextImpl::OnMemoryDump(
400 const base::trace_event::MemoryDumpArgs& args, 469 const base::trace_event::MemoryDumpArgs& args,
401 base::trace_event::ProcessMemoryDump* pmd) { 470 base::trace_event::ProcessMemoryDump* pmd) {
402 for (const auto& it : namespaces_) { 471 for (const auto& it : namespaces_) {
403 it.second->OnMemoryDump(pmd); 472 it.second->OnMemoryDump(pmd);
404 } 473 }
405 if (session_storage_database_) 474 if (session_storage_database_)
406 session_storage_database_->OnMemoryDump(pmd); 475 session_storage_database_->OnMemoryDump(pmd);
407 return true; 476 return true;
408 } 477 }
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
470 if (!deletable_persistent_namespace_ids_.empty()) { 539 if (!deletable_persistent_namespace_ids_.empty()) {
471 task_runner_->PostDelayedTask( 540 task_runner_->PostDelayedTask(
472 FROM_HERE, base::Bind( 541 FROM_HERE, base::Bind(
473 &DOMStorageContextImpl::DeleteNextUnusedNamespace, 542 &DOMStorageContextImpl::DeleteNextUnusedNamespace,
474 this), 543 this),
475 base::TimeDelta::FromSeconds(kSessionStoraceScavengingSeconds)); 544 base::TimeDelta::FromSeconds(kSessionStoraceScavengingSeconds));
476 } 545 }
477 } 546 }
478 547
479 } // namespace content 548 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698