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

Side by Side Diff: components/memory_pressure/direct_memory_pressure_calculator_linux.cc

Issue 2874553004: Remove memory_pressure component. (Closed)
Patch Set: Created 3 years, 7 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
OLDNEW
(Empty)
1 // Copyright 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 "components/memory_pressure/direct_memory_pressure_calculator_linux.h"
6
7 #include "base/files/file_util.h"
8 #include "base/process/process_metrics.h"
9 #include "base/strings/string_number_conversions.h"
10 #include "base/strings/string_split.h"
11 #include "base/strings/string_util.h"
12 #include "base/sys_info.h"
13 #include "base/threading/thread_restrictions.h"
14
15 namespace memory_pressure {
16
17 namespace {
18
19 const int kKiBperMiB = 1024;
20
21 // Used to calculate a moving average of faults/sec. Our sample times are
22 // inconsistent because MemoryPressureMonitor calls
23 // CalculateCurrentPressureLevel more frequently when memory pressure is high,
24 // and because we're measuring CPU time instead of real time. So our
25 // exponentially weighted moving average is generalized to a low-pass filter.
26 //
27 // Represents the amount of CPU time, in seconds, for a sample to be 50%
28 // forgotten in our moving average. Systems with more CPUs that are under high
29 // load will have a moving average that changes more quickly than a system with
30 // fewer CPUs under the same load. Do not normalize based on the number of CPUs
31 // because this behavior is accurate: if a system with a large number of CPUs
32 // is getting lots of work done without page faulting, it must not be under
33 // memory pressure.
34 //
35 // TODO(thomasanderson): Experimentally determine the correct value for this
36 // constant.
37 const double kLowPassHalfLife = 30.0;
38
39 // Returns the amount of memory that is available for use right now, or that can
40 // be easily reclaimed by the OS, in MBs.
41 int GetAvailableSystemMemoryMiB(const base::SystemMemoryInfoKB* mem_info) {
42 return mem_info->available
43 ? mem_info->available / kKiBperMiB
44 : (mem_info->free + mem_info->buffers + mem_info->cached) /
45 kKiBperMiB;
46 }
47
48 } // namespace
49
50 // Thresholds at which we consider the system being under moderate/critical
51 // memory pressure. They represent the percentage of system memory in use.
52 const int DirectMemoryPressureCalculator::kDefaultModerateThresholdPc = 70;
53 const int DirectMemoryPressureCalculator::kDefaultCriticalThresholdPc = 90;
54
55 DirectMemoryPressureCalculator::DirectMemoryPressureCalculator()
56 : moderate_threshold_mb_(0),
57 critical_threshold_mb_(0) {
58 InferThresholds();
59 InitPageFaultMonitor();
60 }
61
62 DirectMemoryPressureCalculator::DirectMemoryPressureCalculator(
63 int moderate_threshold_mb,
64 int critical_threshold_mb)
65 : moderate_threshold_mb_(moderate_threshold_mb),
66 critical_threshold_mb_(critical_threshold_mb) {
67 DCHECK_GE(moderate_threshold_mb_, critical_threshold_mb_);
68 DCHECK_LE(0, critical_threshold_mb_);
69 InitPageFaultMonitor();
70 }
71
72 DirectMemoryPressureCalculator::MemoryPressureLevel
73 DirectMemoryPressureCalculator::PressureCausedByThrashing(
74 const base::SystemMemoryInfoKB& mem_info) {
75 base::TimeDelta new_user_exec_time = GetUserCpuTimeSinceBoot();
76 if (new_user_exec_time == base::TimeDelta())
77 return MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE;
78 uint64_t new_major_page_faults = mem_info.pgmajfault;
79 if (new_user_exec_time != base::TimeDelta() && new_major_page_faults &&
80 (new_user_exec_time - last_user_exec_time_) != base::TimeDelta()) {
81 double delta_user_exec_time =
82 (new_user_exec_time - last_user_exec_time_).InSecondsF();
83 double delta_major_page_faults =
84 new_major_page_faults - last_major_page_faults_;
85
86 double sampled_faults_per_second =
87 delta_major_page_faults / delta_user_exec_time;
88
89 double adjusted_ewma_coefficient =
90 1 - exp2(-delta_user_exec_time / low_pass_half_life_seconds_);
91
92 current_faults_per_second_ =
93 adjusted_ewma_coefficient * sampled_faults_per_second +
94 (1 - adjusted_ewma_coefficient) * current_faults_per_second_;
95
96 last_user_exec_time_ = new_user_exec_time;
97 last_major_page_faults_ = new_major_page_faults;
98 }
99
100 if (current_faults_per_second_ >
101 critical_multiplier_ * AverageFaultsPerSecond()) {
102 return MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL;
103 }
104 if (current_faults_per_second_ >
105 moderate_multiplier_ * AverageFaultsPerSecond()) {
106 return MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE;
107 }
108 return MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE;
109 }
110
111 DirectMemoryPressureCalculator::MemoryPressureLevel
112 DirectMemoryPressureCalculator::PressureCausedByOOM(
113 const base::SystemMemoryInfoKB& mem_info) {
114 int phys_free = GetAvailableSystemMemoryMiB(&mem_info);
115
116 if (phys_free <= critical_threshold_mb_)
117 return MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL;
118 if (phys_free <= moderate_threshold_mb_)
119 return MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE;
120 return MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE;
121 }
122
123 DirectMemoryPressureCalculator::MemoryPressureLevel
124 DirectMemoryPressureCalculator::CalculateCurrentPressureLevel() {
125 base::SystemMemoryInfoKB mem_info = {};
126 if (!GetSystemMemoryInfo(&mem_info))
127 return MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE;
128
129 return std::max(PressureCausedByThrashing(mem_info),
130 PressureCausedByOOM(mem_info));
131 }
132
133 bool DirectMemoryPressureCalculator::GetSystemMemoryInfo(
134 base::SystemMemoryInfoKB* mem_info) const {
135 return base::GetSystemMemoryInfo(mem_info);
136 }
137
138 base::TimeDelta DirectMemoryPressureCalculator::GetUserCpuTimeSinceBoot()
139 const {
140 return base::GetUserCpuTimeSinceBoot();
141 }
142
143 void DirectMemoryPressureCalculator::InferThresholds() {
144 base::SystemMemoryInfoKB mem_info = {};
145 if (!GetSystemMemoryInfo(&mem_info))
146 return;
147
148 moderate_threshold_mb_ =
149 mem_info.total * (100 - kDefaultModerateThresholdPc) / 100 / kKiBperMiB;
150 critical_threshold_mb_ =
151 mem_info.total * (100 - kDefaultCriticalThresholdPc) / 100 / kKiBperMiB;
152 }
153
154 void DirectMemoryPressureCalculator::InitPageFaultMonitor() {
155 low_pass_half_life_seconds_ = kLowPassHalfLife;
156 last_user_exec_time_ = GetUserCpuTimeSinceBoot();
157 base::SystemMemoryInfoKB mem_info = {};
158 last_major_page_faults_ =
159 GetSystemMemoryInfo(&mem_info) ? mem_info.pgmajfault : 0;
160 current_faults_per_second_ = AverageFaultsPerSecond();
161 }
162
163 double DirectMemoryPressureCalculator::AverageFaultsPerSecond() const {
164 return last_major_page_faults_ == 0
165 ? last_user_exec_time_.InSecondsF() / last_major_page_faults_
166 : 0;
167 }
168
169 } // namespace memory_pressure
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698