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 "content/common/host_discardable_shared_memory_manager.h" | 5 #include "content/common/host_discardable_shared_memory_manager.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/atomic_sequence_num.h" | 9 #include "base/atomic_sequence_num.h" |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
352 break; | 352 break; |
353 | 353 |
354 // Stop eviction attempts when the LRU segment is currently in use. | 354 // Stop eviction attempts when the LRU segment is currently in use. |
355 if (segments_.front()->memory()->last_known_usage() >= current_time) | 355 if (segments_.front()->memory()->last_known_usage() >= current_time) |
356 break; | 356 break; |
357 | 357 |
358 std::pop_heap(segments_.begin(), segments_.end(), CompareMemoryUsageTime); | 358 std::pop_heap(segments_.begin(), segments_.end(), CompareMemoryUsageTime); |
359 scoped_refptr<MemorySegment> segment = segments_.back(); | 359 scoped_refptr<MemorySegment> segment = segments_.back(); |
360 segments_.pop_back(); | 360 segments_.pop_back(); |
361 | 361 |
362 // Attempt to purge LRU segment. When successful, released the memory. | 362 // Attempt to purge and truncate LRU segment. When successful, as much |
363 if (segment->memory()->Purge(current_time)) { | 363 // memory as possible will be released to the OS. How much memory is |
| 364 // released depends on the platform. The child process should perform |
| 365 // periodic cleanup to ensure that all memory is release within a |
| 366 // reasonable amount of time. |
| 367 if (segment->memory()->PurgeAndTruncate(current_time)) { |
364 ReleaseMemory(segment->memory()); | 368 ReleaseMemory(segment->memory()); |
365 continue; | 369 continue; |
366 } | 370 } |
367 | 371 |
368 // Add memory segment (with updated usage timestamp) back on heap after | 372 // Add memory segment (with updated usage timestamp) back on heap after |
369 // failed attempt to purge it. | 373 // failed attempt to purge it. |
370 segments_.push_back(segment.get()); | 374 segments_.push_back(segment.get()); |
371 std::push_heap(segments_.begin(), segments_.end(), CompareMemoryUsageTime); | 375 std::push_heap(segments_.begin(), segments_.end(), CompareMemoryUsageTime); |
372 } | 376 } |
373 | 377 |
374 if (bytes_allocated_ != bytes_allocated_before_purging) | 378 if (bytes_allocated_ != bytes_allocated_before_purging) |
375 BytesAllocatedChanged(bytes_allocated_); | 379 BytesAllocatedChanged(bytes_allocated_); |
376 } | 380 } |
377 | 381 |
378 void HostDiscardableSharedMemoryManager::ReleaseMemory( | 382 void HostDiscardableSharedMemoryManager::ReleaseMemory( |
379 base::DiscardableSharedMemory* memory) { | 383 base::DiscardableSharedMemory* memory) { |
380 lock_.AssertAcquired(); | 384 lock_.AssertAcquired(); |
381 | 385 |
382 size_t size = memory->mapped_size(); | 386 size_t size = memory->mapped_size(); |
383 DCHECK_GE(bytes_allocated_, size); | 387 DCHECK_GE(bytes_allocated_, size); |
384 bytes_allocated_ -= size; | 388 bytes_allocated_ -= size; |
385 | 389 |
386 #if defined(DISCARDABLE_SHARED_MEMORY_SHRINKING) | |
387 // Shrink memory segment. This will immediately release the memory to the OS. | |
388 memory->Shrink(); | |
389 #endif | |
390 | |
391 // This will unmap the memory segment and drop our reference. The result | 390 // This will unmap the memory segment and drop our reference. The result |
392 // is that the memory will be released to the OS if the child process is | 391 // is that the memory will be released to the OS if the child process is |
393 // no longer referencing it. | 392 // no longer referencing it. |
394 // Note: We intentionally leave the segment in the |segments| vector to | 393 // Note: We intentionally leave the segment in the |segments| vector to |
395 // avoid reconstructing the heap. The element will be removed from the heap | 394 // avoid reconstructing the heap. The element will be removed from the heap |
396 // when its last usage time is older than all other segments. | 395 // when its last usage time is older than all other segments. |
397 memory->Close(); | 396 memory->Close(); |
398 } | 397 } |
399 | 398 |
400 void HostDiscardableSharedMemoryManager::BytesAllocatedChanged( | 399 void HostDiscardableSharedMemoryManager::BytesAllocatedChanged( |
(...skipping 19 matching lines...) Expand all Loading... |
420 | 419 |
421 enforce_memory_policy_pending_ = true; | 420 enforce_memory_policy_pending_ = true; |
422 base::MessageLoop::current()->PostDelayedTask( | 421 base::MessageLoop::current()->PostDelayedTask( |
423 FROM_HERE, | 422 FROM_HERE, |
424 base::Bind(&HostDiscardableSharedMemoryManager::EnforceMemoryPolicy, | 423 base::Bind(&HostDiscardableSharedMemoryManager::EnforceMemoryPolicy, |
425 weak_ptr_factory_.GetWeakPtr()), | 424 weak_ptr_factory_.GetWeakPtr()), |
426 base::TimeDelta::FromMilliseconds(kEnforceMemoryPolicyDelayMs)); | 425 base::TimeDelta::FromMilliseconds(kEnforceMemoryPolicyDelayMs)); |
427 } | 426 } |
428 | 427 |
429 } // namespace content | 428 } // namespace content |
OLD | NEW |