| OLD | NEW |
| (Empty) | |
| 1 // Copyright (c) 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "content/browser/memory/memory_monitor_mac.h" |
| 6 |
| 7 #include <math.h> |
| 8 #include <sys/sysctl.h> |
| 9 |
| 10 #include <algorithm> |
| 11 |
| 12 #include "base/memory/ptr_util.h" |
| 13 #include "base/process/process_metrics.h" |
| 14 #include "content/browser/memory/memory_coordinator.h" |
| 15 |
| 16 namespace content { |
| 17 |
| 18 namespace { |
| 19 |
| 20 // The number of bits to shift to convert KiB to MiB. |
| 21 const int kShiftKiBtoMiB = 10; |
| 22 |
| 23 // The rate at which to adjust the "critical" boundary, in MiB/s. |
| 24 const int kCriticalAdjustmentMBS = 1; |
| 25 |
| 26 } // namespace |
| 27 |
| 28 MemoryMonitorMac::MemoryMonitorMac(MemoryMonitorDelegate* delegate, |
| 29 base::TimeDelta poll_interval) |
| 30 : delegate_(delegate), |
| 31 poll_interval_adjustment_mb_(poll_interval.InSeconds() * |
| 32 kCriticalAdjustmentMBS), |
| 33 critical_free_mb_(0) { |
| 34 // Poll interval has to be at least 1s. |
| 35 DCHECK_LE(1, poll_interval.InSeconds()); |
| 36 } |
| 37 |
| 38 MemoryMonitorMac::~MemoryMonitorMac() {} |
| 39 |
| 40 int MemoryMonitorMac::GetFreeMemoryUntilCriticalMB() { |
| 41 // Get the amount of free memory in the system. The "free" amount is a poor |
| 42 // indication because it doesn't take into consideration memory that is |
| 43 // in use but can be easily freed, such as disk buffers. |
| 44 base::SystemMemoryInfoKB mem_info = {}; |
| 45 delegate_->GetSystemMemoryInfo(&mem_info); |
| 46 int free_mem = mem_info.free >> kShiftKiBtoMiB; |
| 47 |
| 48 // Get the current system memory pressure. |
| 49 int mac_memory_pressure; |
| 50 bool success = delegate_->GetSystemMemoryPressure(&mac_memory_pressure); |
| 51 DCHECK(success); |
| 52 |
| 53 // Adjust the "critical threshold" according to current memory pressure. |
| 54 switch (mac_memory_pressure) { |
| 55 case DISPATCH_MEMORYPRESSURE_NORMAL: |
| 56 // Under normal operation, allow more and more memory to be used. |
| 57 critical_free_mb_ = |
| 58 std::max(0LL, critical_free_mb_ - poll_interval_adjustment_mb_); |
| 59 break; |
| 60 case DISPATCH_MEMORYPRESSURE_WARN: { |
| 61 // Once free memory starts to get low, gradually reduce the amount |
| 62 // of memory that con be used. |
| 63 int half_free = free_mem >> 1; |
| 64 if (critical_free_mb_ < half_free) |
| 65 critical_free_mb_ = half_free; |
| 66 else if (critical_free_mb_ < free_mem) |
| 67 critical_free_mb_ += poll_interval_adjustment_mb_; |
| 68 } break; |
| 69 case DISPATCH_MEMORYPRESSURE_CRITICAL: |
| 70 // When memory pressure is critical, assume that system is about to swap. |
| 71 critical_free_mb_ = free_mem; |
| 72 break; |
| 73 } |
| 74 |
| 75 // Return the amount of memory until critical. |
| 76 return free_mem - critical_free_mb_; |
| 77 } |
| 78 |
| 79 // static |
| 80 std::unique_ptr<MemoryMonitorMac> MemoryMonitorMac::Create( |
| 81 MemoryMonitorDelegate* delegate, |
| 82 base::TimeDelta poll_interval) { |
| 83 return base::MakeUnique<MemoryMonitorMac>(delegate, poll_interval); |
| 84 } |
| 85 |
| 86 // Implementation of factory function defined in memory_monitor.h. |
| 87 std::unique_ptr<MemoryMonitor> CreateMemoryMonitor() { |
| 88 return MemoryMonitorMac::Create( |
| 89 MemoryMonitorMacDelegate::GetInstance(), |
| 90 MemoryCoordinator::GetInstance()->GetMonitoringInterval()); |
| 91 } |
| 92 |
| 93 MemoryMonitorMacDelegate* MemoryMonitorMacDelegate::GetInstance() { |
| 94 return base::Singleton< |
| 95 MemoryMonitorMacDelegate, |
| 96 base::LeakySingletonTraits<MemoryMonitorMacDelegate>>::get(); |
| 97 } |
| 98 |
| 99 bool MemoryMonitorMacDelegate::GetSystemMemoryPressure(int* mem_pressure) { |
| 100 size_t length = sizeof(*mem_pressure); |
| 101 sysctlbyname("kern.memorystatus_vm_pressure_level", mem_pressure, &length, |
| 102 nullptr, 0); |
| 103 return true; |
| 104 } |
| 105 |
| 106 } // namespace content |
| OLD | NEW |