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

Side by Side Diff: base/chromeos/memory_pressure_observer_chromeos.cc

Issue 874483008: Add UMA stats to get the quality of service of memory pressure handling scheme in ChromeOS. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Address the review comments. Created 5 years, 10 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
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/chromeos/memory_pressure_observer_chromeos.h" 5 #include "base/chromeos/memory_pressure_observer_chromeos.h"
6 6
7 #include "base/message_loop/message_loop.h" 7 #include "base/message_loop/message_loop.h"
8 #include "base/metrics/histogram_macros.h"
8 #include "base/process/process_metrics.h" 9 #include "base/process/process_metrics.h"
9 #include "base/time/time.h" 10 #include "base/time/time.h"
10 11
11 namespace base { 12 namespace base {
12 13
13 namespace { 14 namespace {
14 15
15 // The time between memory pressure checks. While under critical pressure, this 16 // The time between memory pressure checks. While under critical pressure, this
16 // is also the timer to repeat cleanup attempts. 17 // is also the timer to repeat cleanup attempts.
17 const int kMemoryPressureIntervalMs = 1000; 18 const int kMemoryPressureIntervalMs = 1000;
18 19
19 // The time which should pass between two moderate memory pressure calls. 20 // The time which should pass between two moderate memory pressure calls.
20 const int kModerateMemoryPressureCooldownMs = 10000; 21 const int kModerateMemoryPressureCooldownMs = 10000;
21 22
22 // Number of event polls before the next moderate pressure event can be sent. 23 // Number of event polls before the next moderate pressure event can be sent.
23 const int kModerateMemoryPressureCooldown = 24 const int kModerateMemoryPressureCooldown =
24 kModerateMemoryPressureCooldownMs / kMemoryPressureIntervalMs; 25 kModerateMemoryPressureCooldownMs / kMemoryPressureIntervalMs;
25 26
26 // Threshold constants to emit pressure events. 27 // Threshold constants to emit pressure events.
27 const int kNormalMemoryPressureModerateThresholdPercent = 60; 28 const int kNormalMemoryPressureModerateThresholdPercent = 60;
28 const int kNormalMemoryPressureCriticalThresholdPercent = 90; 29 const int kNormalMemoryPressureCriticalThresholdPercent = 90;
29 const int kAggressiveMemoryPressureModerateThresholdPercent = 35; 30 const int kAggressiveMemoryPressureModerateThresholdPercent = 35;
30 const int kAggressiveMemoryPressureCriticalThresholdPercent = 70; 31 const int kAggressiveMemoryPressureCriticalThresholdPercent = 70;
31 32
33 // The number used to magnify the fraction of time spent in non critical state.
34 const int kNonCriticalTimeFractionMagnification = 1000000;
35
32 // Converts a |MemoryPressureThreshold| value into a used memory percentage for 36 // Converts a |MemoryPressureThreshold| value into a used memory percentage for
33 // the moderate pressure event. 37 // the moderate pressure event.
34 int GetModerateMemoryThresholdInPercent( 38 int GetModerateMemoryThresholdInPercent(
35 MemoryPressureObserverChromeOS::MemoryPressureThresholds thresholds) { 39 MemoryPressureObserverChromeOS::MemoryPressureThresholds thresholds) {
36 return thresholds == MemoryPressureObserverChromeOS:: 40 return thresholds == MemoryPressureObserverChromeOS::
37 THRESHOLD_AGGRESSIVE_CACHE_DISCARD || 41 THRESHOLD_AGGRESSIVE_CACHE_DISCARD ||
38 thresholds == MemoryPressureObserverChromeOS::THRESHOLD_AGGRESSIVE 42 thresholds == MemoryPressureObserverChromeOS::THRESHOLD_AGGRESSIVE
39 ? kAggressiveMemoryPressureModerateThresholdPercent 43 ? kAggressiveMemoryPressureModerateThresholdPercent
40 : kNormalMemoryPressureModerateThresholdPercent; 44 : kNormalMemoryPressureModerateThresholdPercent;
41 } 45 }
42 46
43 // Converts a |MemoryPressureThreshold| value into a used memory percentage for 47 // Converts a |MemoryPressureThreshold| value into a used memory percentage for
44 // the critical pressure event. 48 // the critical pressure event.
45 int GetCriticalMemoryThresholdInPercent( 49 int GetCriticalMemoryThresholdInPercent(
46 MemoryPressureObserverChromeOS::MemoryPressureThresholds thresholds) { 50 MemoryPressureObserverChromeOS::MemoryPressureThresholds thresholds) {
47 return thresholds == MemoryPressureObserverChromeOS:: 51 return thresholds == MemoryPressureObserverChromeOS::
48 THRESHOLD_AGGRESSIVE_TAB_DISCARD || 52 THRESHOLD_AGGRESSIVE_TAB_DISCARD ||
49 thresholds == MemoryPressureObserverChromeOS::THRESHOLD_AGGRESSIVE 53 thresholds == MemoryPressureObserverChromeOS::THRESHOLD_AGGRESSIVE
50 ? kAggressiveMemoryPressureCriticalThresholdPercent 54 ? kAggressiveMemoryPressureCriticalThresholdPercent
51 : kNormalMemoryPressureCriticalThresholdPercent; 55 : kNormalMemoryPressureCriticalThresholdPercent;
52 } 56 }
53 57
58 // Computes the fraction of time spent in the non critical state. Multiple the
59 // fraction with 1000000 to magnify the result for better comparison between
Mr4D (OOO till 08-26) 2015/02/01 10:16:34 Maybe: Computes the by kNonCriticalTimeFractionMa
60 // different memory management schemes.
61 int GetNonCriticalTimeRatio(TimeDelta critical_delta,
62 TimeDelta non_critical_delta) {
63 return (kNonCriticalTimeFractionMagnification *
64 non_critical_delta.InMilliseconds()) /
65 ((non_critical_delta + critical_delta).InMilliseconds());
66 }
67
68 void RecordNonCriticalTimeRatio(int non_critical_fraction) {
69 UMA_HISTOGRAM_COUNTS("ChromeOS.MemoryPressureHandleQuality.NonCriticalRatio",
70 non_critical_fraction);
71 }
72
54 // Converts free percent of memory into a memory pressure value. 73 // Converts free percent of memory into a memory pressure value.
55 MemoryPressureListener::MemoryPressureLevel GetMemoryPressureLevelFromFillLevel( 74 MemoryPressureListener::MemoryPressureLevel GetMemoryPressureLevelFromFillLevel(
56 int actual_fill_level, 75 int actual_fill_level,
57 int moderate_threshold, 76 int moderate_threshold,
58 int critical_threshold) { 77 int critical_threshold) {
59 if (actual_fill_level < moderate_threshold) 78 if (actual_fill_level < moderate_threshold)
60 return MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE; 79 return MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE;
61 return actual_fill_level < critical_threshold 80 return actual_fill_level < critical_threshold
62 ? MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE 81 ? MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE
63 : MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL; 82 : MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL;
64 } 83 }
65 84
66 } // namespace 85 } // namespace
67 86
68 MemoryPressureObserverChromeOS::MemoryPressureObserverChromeOS( 87 MemoryPressureObserverChromeOS::MemoryPressureObserverChromeOS(
69 MemoryPressureThresholds thresholds) 88 MemoryPressureThresholds thresholds)
70 : current_memory_pressure_level_( 89 : current_memory_pressure_level_(
71 MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE), 90 MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE),
72 moderate_pressure_repeat_count_(0), 91 moderate_pressure_repeat_count_(0),
73 moderate_pressure_threshold_percent_( 92 moderate_pressure_threshold_percent_(
74 GetModerateMemoryThresholdInPercent(thresholds)), 93 GetModerateMemoryThresholdInPercent(thresholds)),
75 critical_pressure_threshold_percent_( 94 critical_pressure_threshold_percent_(
76 GetCriticalMemoryThresholdInPercent(thresholds)), 95 GetCriticalMemoryThresholdInPercent(thresholds)),
96 non_critical_start_time_(TimeTicks::Now()),
97 critical_start_time_(TimeTicks::Now()),
77 weak_ptr_factory_(this) { 98 weak_ptr_factory_(this) {
78 StartObserving(); 99 StartObserving();
79 } 100 }
80 101
81 MemoryPressureObserverChromeOS::~MemoryPressureObserverChromeOS() { 102 MemoryPressureObserverChromeOS::~MemoryPressureObserverChromeOS() {
103 // Record the percentage for the last time.
Mr4D (OOO till 08-26) 2015/02/01 10:16:34 What about: // Before shutting down send the qual
104 if (GetMemoryPressureLevelFromFillLevel(
105 GetUsedMemoryInPercent(), moderate_pressure_threshold_percent_,
106 critical_pressure_threshold_percent_) ==
107 MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL) {
108 int fraction = GetNonCriticalTimeRatio(
109 TimeTicks::Now() - critical_start_time_,
110 critical_start_time_ - non_critical_start_time_);
111 RecordNonCriticalTimeRatio(fraction);
112 } else {
113 RecordNonCriticalTimeRatio(kNonCriticalTimeFractionMagnification);
114 }
115
82 StopObserving(); 116 StopObserving();
83 } 117 }
84 118
85 void MemoryPressureObserverChromeOS::ScheduleEarlyCheck() { 119 void MemoryPressureObserverChromeOS::ScheduleEarlyCheck() {
86 MessageLoop::current()->PostTask( 120 MessageLoop::current()->PostTask(
87 FROM_HERE, 121 FROM_HERE,
88 Bind(&MemoryPressureObserverChromeOS::CheckMemoryPressure, 122 Bind(&MemoryPressureObserverChromeOS::CheckMemoryPressure,
89 weak_ptr_factory_.GetWeakPtr())); 123 weak_ptr_factory_.GetWeakPtr()));
90 } 124 }
91 125
92 void MemoryPressureObserverChromeOS::StartObserving() { 126 void MemoryPressureObserverChromeOS::StartObserving() {
93 timer_.Start(FROM_HERE, 127 timer_.Start(FROM_HERE,
94 TimeDelta::FromMilliseconds(kMemoryPressureIntervalMs), 128 TimeDelta::FromMilliseconds(kMemoryPressureIntervalMs),
95 Bind(&MemoryPressureObserverChromeOS::CheckMemoryPressure, 129 Bind(&MemoryPressureObserverChromeOS::CheckMemoryPressure,
96 weak_ptr_factory_.GetWeakPtr())); 130 weak_ptr_factory_.GetWeakPtr()));
97 } 131 }
98 132
99 void MemoryPressureObserverChromeOS::StopObserving() { 133 void MemoryPressureObserverChromeOS::StopObserving() {
100 // If StartObserving failed, StopObserving will still get called. 134 // If StartObserving failed, StopObserving will still get called.
101 timer_.Stop(); 135 timer_.Stop();
102 } 136 }
103 137
104 void MemoryPressureObserverChromeOS::CheckMemoryPressure() { 138 void MemoryPressureObserverChromeOS::CheckMemoryPressure() {
105 MemoryPressureListener::MemoryPressureLevel old_pressure = 139 MemoryPressureListener::MemoryPressureLevel old_pressure =
106 current_memory_pressure_level_; 140 current_memory_pressure_level_;
107 current_memory_pressure_level_ = 141 current_memory_pressure_level_ =
108 GetMemoryPressureLevelFromFillLevel(GetUsedMemoryInPercent(), 142 GetMemoryPressureLevelFromFillLevel(GetUsedMemoryInPercent(),
109 moderate_pressure_threshold_percent_, 143 moderate_pressure_threshold_percent_,
110 critical_pressure_threshold_percent_); 144 critical_pressure_threshold_percent_);
145
146 // Record the quality of service of memory pressure handling.
147 if (old_pressure != current_memory_pressure_level_) {
148 TimeTicks now = TimeTicks::Now();
149 if (old_pressure ==
150 MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL) {
151 // When leaving the critical memory pressure, we compute the fraction of
152 // time spent in the non critical vs. the critical state. A larger value
153 // indicates a better management scheme.
154 int fraction = GetNonCriticalTimeRatio(
155 now - critical_start_time_,
156 critical_start_time_ - non_critical_start_time_);
157 RecordNonCriticalTimeRatio(fraction);
158 non_critical_start_time_ = now;
159 } else if (current_memory_pressure_level_ ==
160 MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL) {
161 critical_start_time_ = now;
162 }
163 }
164
111 // In case there is no memory pressure we do not notify. 165 // In case there is no memory pressure we do not notify.
112 if (current_memory_pressure_level_ == 166 if (current_memory_pressure_level_ ==
113 MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE) { 167 MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE) {
114 return; 168 return;
115 } 169 }
116 if (old_pressure == current_memory_pressure_level_) { 170 if (old_pressure == current_memory_pressure_level_) {
117 // If the memory pressure is still at the same level, we notify again for a 171 // If the memory pressure is still at the same level, we notify again for a
118 // critical level. In case of a moderate level repeat however, we only send 172 // critical level. In case of a moderate level repeat however, we only send
119 // a notification after a certain time has passed. 173 // a notification after a certain time has passed.
120 if (current_memory_pressure_level_ == 174 if (current_memory_pressure_level_ ==
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
168 // Available memory is the sum of free, swap and easy reclaimable memory. 222 // Available memory is the sum of free, swap and easy reclaimable memory.
169 int available_memory = 223 int available_memory =
170 info.free + info.swap_free / kSwapWeight + file_memory; 224 info.free + info.swap_free / kSwapWeight + file_memory;
171 225
172 DCHECK(available_memory < total_memory); 226 DCHECK(available_memory < total_memory);
173 int percentage = ((total_memory - available_memory) * 100) / total_memory; 227 int percentage = ((total_memory - available_memory) * 100) / total_memory;
174 return percentage; 228 return percentage;
175 } 229 }
176 230
177 } // namespace base 231 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698