OLD | NEW |
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" |
(...skipping 17 matching lines...) Expand all Loading... |
28 bytes_to_keep_under_moderate_pressure), | 28 bytes_to_keep_under_moderate_pressure), |
29 hard_memory_limit_expiration_time_(hard_memory_limit_expiration_time) { | 29 hard_memory_limit_expiration_time_(hard_memory_limit_expiration_time) { |
30 BytesAllocatedChanged(bytes_allocated_); | 30 BytesAllocatedChanged(bytes_allocated_); |
31 } | 31 } |
32 | 32 |
33 DiscardableMemoryManager::~DiscardableMemoryManager() { | 33 DiscardableMemoryManager::~DiscardableMemoryManager() { |
34 DCHECK(allocations_.empty()); | 34 DCHECK(allocations_.empty()); |
35 DCHECK_EQ(0u, bytes_allocated_); | 35 DCHECK_EQ(0u, bytes_allocated_); |
36 } | 36 } |
37 | 37 |
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) { | 38 void DiscardableMemoryManager::SetMemoryLimit(size_t bytes) { |
53 AutoLock lock(lock_); | 39 AutoLock lock(lock_); |
54 memory_limit_ = bytes; | 40 memory_limit_ = bytes; |
55 PurgeIfNotUsedSinceTimestampUntilUsageIsWithinLimitWithLockAcquired( | 41 PurgeIfNotUsedSinceTimestampUntilUsageIsWithinLimitWithLockAcquired( |
56 Now(), memory_limit_); | 42 Now(), memory_limit_); |
57 } | 43 } |
58 | 44 |
59 void DiscardableMemoryManager::SetSoftMemoryLimit(size_t bytes) { | 45 void DiscardableMemoryManager::SetSoftMemoryLimit(size_t bytes) { |
60 AutoLock lock(lock_); | 46 AutoLock lock(lock_); |
61 soft_memory_limit_ = bytes; | 47 soft_memory_limit_ = bytes; |
62 } | 48 } |
63 | 49 |
64 void DiscardableMemoryManager::SetBytesToKeepUnderModeratePressure( | 50 void DiscardableMemoryManager::SetBytesToKeepUnderModeratePressure( |
65 size_t bytes) { | 51 size_t bytes) { |
66 AutoLock lock(lock_); | 52 AutoLock lock(lock_); |
67 bytes_to_keep_under_moderate_pressure_ = bytes; | 53 bytes_to_keep_under_moderate_pressure_ = bytes; |
68 } | 54 } |
69 | 55 |
70 void DiscardableMemoryManager::SetHardMemoryLimitExpirationTime( | 56 void DiscardableMemoryManager::SetHardMemoryLimitExpirationTime( |
71 TimeDelta hard_memory_limit_expiration_time) { | 57 TimeDelta hard_memory_limit_expiration_time) { |
72 AutoLock lock(lock_); | 58 AutoLock lock(lock_); |
73 hard_memory_limit_expiration_time_ = hard_memory_limit_expiration_time; | 59 hard_memory_limit_expiration_time_ = hard_memory_limit_expiration_time; |
74 } | 60 } |
75 | 61 |
76 bool DiscardableMemoryManager::ReduceMemoryUsage() { | 62 bool DiscardableMemoryManager::ReduceMemoryUsage() { |
77 return PurgeIfNotUsedSinceHardLimitCutoffUntilWithinSoftMemoryLimit(); | 63 return PurgeIfNotUsedSinceHardLimitCutoffUntilWithinSoftMemoryLimit(); |
78 } | 64 } |
79 | 65 |
| 66 void |
| 67 DiscardableMemoryManager::ReduceMemoryUsageUntilWithinModeratePressureLimit() { |
| 68 PurgeUntilWithinBytesToKeepUnderModeratePressure(); |
| 69 } |
| 70 |
80 void DiscardableMemoryManager::Register(Allocation* allocation, size_t bytes) { | 71 void DiscardableMemoryManager::Register(Allocation* allocation, size_t bytes) { |
81 AutoLock lock(lock_); | 72 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()); | 73 DCHECK(allocations_.Peek(allocation) == allocations_.end()); |
88 allocations_.Put(allocation, AllocationInfo(bytes)); | 74 allocations_.Put(allocation, AllocationInfo(bytes)); |
89 } | 75 } |
90 | 76 |
91 void DiscardableMemoryManager::Unregister(Allocation* allocation) { | 77 void DiscardableMemoryManager::Unregister(Allocation* allocation) { |
92 AutoLock lock(lock_); | 78 AutoLock lock(lock_); |
93 AllocationMap::iterator it = allocations_.Peek(allocation); | 79 AllocationMap::iterator it = allocations_.Peek(allocation); |
94 DCHECK(it != allocations_.end()); | 80 DCHECK(it != allocations_.end()); |
95 const AllocationInfo& info = it->second; | 81 const AllocationInfo& info = it->second; |
96 | 82 |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
175 AutoLock lock(lock_); | 161 AutoLock lock(lock_); |
176 AllocationMap::const_iterator it = allocations_.Peek(allocation); | 162 AllocationMap::const_iterator it = allocations_.Peek(allocation); |
177 return it != allocations_.end() && it->second.purgable; | 163 return it != allocations_.end() && it->second.purgable; |
178 } | 164 } |
179 | 165 |
180 size_t DiscardableMemoryManager::GetBytesAllocatedForTest() const { | 166 size_t DiscardableMemoryManager::GetBytesAllocatedForTest() const { |
181 AutoLock lock(lock_); | 167 AutoLock lock(lock_); |
182 return bytes_allocated_; | 168 return bytes_allocated_; |
183 } | 169 } |
184 | 170 |
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 | 171 void |
200 DiscardableMemoryManager::PurgeUntilWithinBytesToKeepUnderModeratePressure() { | 172 DiscardableMemoryManager::PurgeUntilWithinBytesToKeepUnderModeratePressure() { |
201 AutoLock lock(lock_); | 173 AutoLock lock(lock_); |
202 | 174 |
203 PurgeIfNotUsedSinceTimestampUntilUsageIsWithinLimitWithLockAcquired( | 175 PurgeIfNotUsedSinceTimestampUntilUsageIsWithinLimitWithLockAcquired( |
204 Now(), bytes_to_keep_under_moderate_pressure_); | 176 Now(), bytes_to_keep_under_moderate_pressure_); |
205 } | 177 } |
206 | 178 |
207 bool DiscardableMemoryManager:: | 179 bool DiscardableMemoryManager:: |
208 PurgeIfNotUsedSinceHardLimitCutoffUntilWithinSoftMemoryLimit() { | 180 PurgeIfNotUsedSinceHardLimitCutoffUntilWithinSoftMemoryLimit() { |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
254 base::debug::SetCrashKeyValue(kDiscardableMemoryUsageKey, | 226 base::debug::SetCrashKeyValue(kDiscardableMemoryUsageKey, |
255 Uint64ToString(new_bytes_allocated)); | 227 Uint64ToString(new_bytes_allocated)); |
256 } | 228 } |
257 | 229 |
258 TimeTicks DiscardableMemoryManager::Now() const { | 230 TimeTicks DiscardableMemoryManager::Now() const { |
259 return TimeTicks::Now(); | 231 return TimeTicks::Now(); |
260 } | 232 } |
261 | 233 |
262 } // namespace internal | 234 } // namespace internal |
263 } // namespace base | 235 } // namespace base |
OLD | NEW |