Chromium Code Reviews| 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; | |
|
chrisha
2016/11/09 21:21:11
Do we have a reason to believe that 50% is the rig
bcwhite
2016/11/09 22:46:54
None at all. Just seemed a reasonable starting gu
chrisha
2016/11/14 18:14:31
Do you have an idea for how we could monitor the p
bcwhite
2016/11/15 23:15:09
I could create a metric that counts the number of
| |
| 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; | |
|
chrisha
2016/11/09 21:21:11
Shouldn't this be *zero*? Critical is defined as s
bcwhite
2016/11/09 22:46:54
Critical is defined as the amount of memory that c
chrisha
2016/11/14 18:14:31
Ah, okay, makes sense.
| |
| 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 |