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

Side by Side Diff: base/memory/discardable_memory_manager.cc

Issue 448173002: Re-land: base: Introduce an explicit call for reducing emulated discardable memory usage. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: disable EmulatedDiscardableMemoryDiscardedWhenWidgetsHidden with lsan Created 6 years, 4 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 | Annotate | Revision Log
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 "base/memory/discardable_memory_manager.h" 5 #include "base/memory/discardable_memory_manager.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/containers/hash_tables.h" 8 #include "base/containers/hash_tables.h"
9 #include "base/containers/mru_cache.h" 9 #include "base/containers/mru_cache.h"
10 #include "base/debug/crash_logging.h" 10 #include "base/debug/crash_logging.h"
11 #include "base/debug/trace_event.h" 11 #include "base/debug/trace_event.h"
12 #include "base/strings/string_number_conversions.h" 12 #include "base/strings/string_number_conversions.h"
13 #include "base/synchronization/lock.h" 13 #include "base/synchronization/lock.h"
14 14
15 namespace base { 15 namespace base {
16 namespace internal { 16 namespace internal {
17 17
18 DiscardableMemoryManager::DiscardableMemoryManager( 18 DiscardableMemoryManager::DiscardableMemoryManager(
19 size_t memory_limit, 19 size_t memory_limit,
20 size_t soft_memory_limit, 20 size_t soft_memory_limit,
21 size_t bytes_to_keep_under_moderate_pressure,
22 TimeDelta hard_memory_limit_expiration_time) 21 TimeDelta hard_memory_limit_expiration_time)
23 : allocations_(AllocationMap::NO_AUTO_EVICT), 22 : allocations_(AllocationMap::NO_AUTO_EVICT),
24 bytes_allocated_(0u), 23 bytes_allocated_(0u),
25 memory_limit_(memory_limit), 24 memory_limit_(memory_limit),
26 soft_memory_limit_(soft_memory_limit), 25 soft_memory_limit_(soft_memory_limit),
27 bytes_to_keep_under_moderate_pressure_(
28 bytes_to_keep_under_moderate_pressure),
29 hard_memory_limit_expiration_time_(hard_memory_limit_expiration_time) { 26 hard_memory_limit_expiration_time_(hard_memory_limit_expiration_time) {
30 BytesAllocatedChanged(bytes_allocated_); 27 BytesAllocatedChanged(bytes_allocated_);
31 } 28 }
32 29
33 DiscardableMemoryManager::~DiscardableMemoryManager() { 30 DiscardableMemoryManager::~DiscardableMemoryManager() {
34 DCHECK(allocations_.empty()); 31 DCHECK(allocations_.empty());
35 DCHECK_EQ(0u, bytes_allocated_); 32 DCHECK_EQ(0u, bytes_allocated_);
36 } 33 }
37 34
38 void DiscardableMemoryManager::RegisterMemoryPressureListener() {
39 AutoLock lock(lock_);
40 DCHECK(base::MessageLoop::current());
41 DCHECK(!memory_pressure_listener_);
42 memory_pressure_listener_.reset(new MemoryPressureListener(base::Bind(
43 &DiscardableMemoryManager::OnMemoryPressure, Unretained(this))));
44 }
45
46 void DiscardableMemoryManager::UnregisterMemoryPressureListener() {
47 AutoLock lock(lock_);
48 DCHECK(memory_pressure_listener_);
49 memory_pressure_listener_.reset();
50 }
51
52 void DiscardableMemoryManager::SetMemoryLimit(size_t bytes) { 35 void DiscardableMemoryManager::SetMemoryLimit(size_t bytes) {
53 AutoLock lock(lock_); 36 AutoLock lock(lock_);
54 memory_limit_ = bytes; 37 memory_limit_ = bytes;
55 PurgeIfNotUsedSinceTimestampUntilUsageIsWithinLimitWithLockAcquired( 38 PurgeIfNotUsedSinceTimestampUntilUsageIsWithinLimitWithLockAcquired(
56 Now(), memory_limit_); 39 Now(), memory_limit_);
57 } 40 }
58 41
59 void DiscardableMemoryManager::SetSoftMemoryLimit(size_t bytes) { 42 void DiscardableMemoryManager::SetSoftMemoryLimit(size_t bytes) {
60 AutoLock lock(lock_); 43 AutoLock lock(lock_);
61 soft_memory_limit_ = bytes; 44 soft_memory_limit_ = bytes;
62 } 45 }
63 46
64 void DiscardableMemoryManager::SetBytesToKeepUnderModeratePressure(
65 size_t bytes) {
66 AutoLock lock(lock_);
67 bytes_to_keep_under_moderate_pressure_ = bytes;
68 }
69
70 void DiscardableMemoryManager::SetHardMemoryLimitExpirationTime( 47 void DiscardableMemoryManager::SetHardMemoryLimitExpirationTime(
71 TimeDelta hard_memory_limit_expiration_time) { 48 TimeDelta hard_memory_limit_expiration_time) {
72 AutoLock lock(lock_); 49 AutoLock lock(lock_);
73 hard_memory_limit_expiration_time_ = hard_memory_limit_expiration_time; 50 hard_memory_limit_expiration_time_ = hard_memory_limit_expiration_time;
74 } 51 }
75 52
76 bool DiscardableMemoryManager::ReduceMemoryUsage() { 53 bool DiscardableMemoryManager::ReduceMemoryUsage() {
77 return PurgeIfNotUsedSinceHardLimitCutoffUntilWithinSoftMemoryLimit(); 54 return PurgeIfNotUsedSinceHardLimitCutoffUntilWithinSoftMemoryLimit();
78 } 55 }
79 56
57 void DiscardableMemoryManager::ReduceMemoryUsageUntilWithinLimit(size_t bytes) {
58 AutoLock lock(lock_);
59 PurgeIfNotUsedSinceTimestampUntilUsageIsWithinLimitWithLockAcquired(Now(),
60 bytes);
61 }
62
80 void DiscardableMemoryManager::Register(Allocation* allocation, size_t bytes) { 63 void DiscardableMemoryManager::Register(Allocation* allocation, size_t bytes) {
81 AutoLock lock(lock_); 64 AutoLock lock(lock_);
82 // A registered memory listener is currently required. This DCHECK can be
83 // moved or removed if we decide that it's useful to relax this condition.
84 // TODO(reveman): Enable this DCHECK when skia and blink are able to
85 // register memory pressure listeners. crbug.com/333907
86 // DCHECK(memory_pressure_listener_);
87 DCHECK(allocations_.Peek(allocation) == allocations_.end()); 65 DCHECK(allocations_.Peek(allocation) == allocations_.end());
88 allocations_.Put(allocation, AllocationInfo(bytes)); 66 allocations_.Put(allocation, AllocationInfo(bytes));
89 } 67 }
90 68
91 void DiscardableMemoryManager::Unregister(Allocation* allocation) { 69 void DiscardableMemoryManager::Unregister(Allocation* allocation) {
92 AutoLock lock(lock_); 70 AutoLock lock(lock_);
93 AllocationMap::iterator it = allocations_.Peek(allocation); 71 AllocationMap::iterator it = allocations_.Peek(allocation);
94 DCHECK(it != allocations_.end()); 72 DCHECK(it != allocations_.end());
95 const AllocationInfo& info = it->second; 73 const AllocationInfo& info = it->second;
96 74
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
175 AutoLock lock(lock_); 153 AutoLock lock(lock_);
176 AllocationMap::const_iterator it = allocations_.Peek(allocation); 154 AllocationMap::const_iterator it = allocations_.Peek(allocation);
177 return it != allocations_.end() && it->second.purgable; 155 return it != allocations_.end() && it->second.purgable;
178 } 156 }
179 157
180 size_t DiscardableMemoryManager::GetBytesAllocatedForTest() const { 158 size_t DiscardableMemoryManager::GetBytesAllocatedForTest() const {
181 AutoLock lock(lock_); 159 AutoLock lock(lock_);
182 return bytes_allocated_; 160 return bytes_allocated_;
183 } 161 }
184 162
185 void DiscardableMemoryManager::OnMemoryPressure(
186 MemoryPressureListener::MemoryPressureLevel pressure_level) {
187 switch (pressure_level) {
188 case MemoryPressureListener::MEMORY_PRESSURE_MODERATE:
189 PurgeUntilWithinBytesToKeepUnderModeratePressure();
190 return;
191 case MemoryPressureListener::MEMORY_PRESSURE_CRITICAL:
192 PurgeAll();
193 return;
194 }
195
196 NOTREACHED();
197 }
198
199 void
200 DiscardableMemoryManager::PurgeUntilWithinBytesToKeepUnderModeratePressure() {
201 AutoLock lock(lock_);
202
203 PurgeIfNotUsedSinceTimestampUntilUsageIsWithinLimitWithLockAcquired(
204 Now(), bytes_to_keep_under_moderate_pressure_);
205 }
206
207 bool DiscardableMemoryManager:: 163 bool DiscardableMemoryManager::
208 PurgeIfNotUsedSinceHardLimitCutoffUntilWithinSoftMemoryLimit() { 164 PurgeIfNotUsedSinceHardLimitCutoffUntilWithinSoftMemoryLimit() {
209 AutoLock lock(lock_); 165 AutoLock lock(lock_);
210 166
211 PurgeIfNotUsedSinceTimestampUntilUsageIsWithinLimitWithLockAcquired( 167 PurgeIfNotUsedSinceTimestampUntilUsageIsWithinLimitWithLockAcquired(
212 Now() - hard_memory_limit_expiration_time_, soft_memory_limit_); 168 Now() - hard_memory_limit_expiration_time_, soft_memory_limit_);
213 169
214 return bytes_allocated_ <= soft_memory_limit_; 170 return bytes_allocated_ <= soft_memory_limit_;
215 } 171 }
216 172
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
254 base::debug::SetCrashKeyValue(kDiscardableMemoryUsageKey, 210 base::debug::SetCrashKeyValue(kDiscardableMemoryUsageKey,
255 Uint64ToString(new_bytes_allocated)); 211 Uint64ToString(new_bytes_allocated));
256 } 212 }
257 213
258 TimeTicks DiscardableMemoryManager::Now() const { 214 TimeTicks DiscardableMemoryManager::Now() const {
259 return TimeTicks::Now(); 215 return TimeTicks::Now();
260 } 216 }
261 217
262 } // namespace internal 218 } // namespace internal
263 } // namespace base 219 } // namespace base
OLDNEW
« no previous file with comments | « base/memory/discardable_memory_manager.h ('k') | base/memory/discardable_memory_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698