OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |