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

Side by Side Diff: components/memory_pressure/memory_pressure_monitor.h

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 // Declares the MemoryPressureMonitor class. This is responsible for monitoring
6 // system-wide memory pressure and dispatching memory pressure signals to
7 // MemoryPressureListener. It is also responsible for rate limiting calls to the
8 // memory pressure subsytem and gathering statistics for UMA.
9 //
10 // The class has a few compile time differences depending on if
11 // MEMORY_PRESSURE_IS_POLLING is defined. For Windows, ChromeOS and Linux
12 // the implementation is polling so MEMORY_PRESSURE_IS_POLLING is defined. For
13 // Mac, iOS and Android it is not defined.
14 //
15 // The difference is that "polling" platforms have no native OS signals
16 // indicating memory pressure. These platforms implement
17 // DirectMemoryPressureCalculator, which is polled on a schedule to check for
18 // memory pressure changes. On non-polling platforms the OS provides a native
19 // signal. This signal is observed by the platform-specific implementation of
20 // MemoryPressureMonitorImpl.
21 //
22 // The memory pressure system periodically repeats memory pressure signals while
23 // under memory pressure (the interval varying depending on the pressure level).
24 // As such, even non-polling platforms require a scheduling mechanism for
25 // repeating notifications. Both implementations share this basic scheduling
26 // subsystem, and also leverage it to make timely UMA reports.
27
28 #ifndef COMPONENTS_MEMORY_PRESSURE_MEMORY_PRESSURE_MONITOR_H_
29 #define COMPONENTS_MEMORY_PRESSURE_MEMORY_PRESSURE_MONITOR_H_
30
31 #include <map>
32 #include <memory>
33
34 #include "base/callback.h"
35 #include "base/memory/weak_ptr.h"
36 #include "base/synchronization/lock.h"
37 #include "base/time/time.h"
38 #include "components/memory_pressure/memory_pressure_listener.h"
39
40 namespace base {
41 class TaskRunner;
42 class TickClock;
43 } // namespace
44
45 namespace memory_pressure {
46
47 class MemoryPressureCalculator;
48 class MemoryPressureStatsCollector;
49
50 #if !defined(MEMORY_PRESSURE_IS_POLLING)
51 // For non-polling platform specific implementation details. An instance of
52 // this class will be encapsulated in the monitor. It will received an injected
53 // callback that routes messages to OnMemoryPressureChanged.
54 class MemoryPressureMonitorImpl;
55 #endif
56
57 // A thread-safe class for directly querying and automatically monitoring
58 // memory pressure. When system memory pressure levels change this class is
59 // responsible for notifying MemoryPressureListeners, and periodically
60 // renotifying them as conditions persist. This class will do its periodic work
61 // on the thread on which it was created. However, it is safe to call
62 // GetCurrentPressureLevel from any thread.
63 //
64 // This class doesn't make use of base::RepeatingTimer as it leaves an orphaned
65 // scheduled task every time it is canceled. This can occur every time a memory
66 // pressure level transition occurs, which has no strict upper bound. Instead
67 // a collection of at most "number of memory pressure level" scheduled tasks
68 // is used, with these tasks being reused as transition levels are crossed and
69 // polling requirements change. See |scheduled_checks_| and
70 // "ScheduleTaskIfNeededLocked" for details.
71 class MemoryPressureMonitor {
72 public:
73 using MemoryPressureLevel = MemoryPressureListener::MemoryPressureLevel;
74
75 // A simple dispatch delegate as a testing seam. Makes unittests much simpler
76 // as they don't need to setup a multithreaded environment.
77 using DispatchCallback = base::Callback<void(MemoryPressureLevel)>;
78
79 #if defined(MEMORY_PRESSURE_IS_POLLING)
80 // The minimum time that must pass between successive polls. This enforces an
81 // upper bound on the rate of calls to the contained MemoryPressureCalculator.
82 // 100ms (10Hz) allows a relatively fast respsonse time for rapidly increasing
83 // memory usage, but limits the amount of work done in the calculator and
84 // stats collection.
85 enum : int { kMinimumTimeBetweenSamplesMs = 100 };
86 // On polling platforms this is required to be somewhat short in order to
87 // observe memory pressure changes as they occur.
88 enum : int { kDefaultPollingIntervalMs = 5000 };
89 #else
90 // On non-polling platforms this is only required for keeping statistics up to
91 // date so can be quite a long period.
92 enum : int { kDefaultPollingIntervalMs = 60000 };
93 #endif
94
95 // Renotification intervals, per pressure level. These are the same on all
96 // platforms. These act as an upper bound on the polling interval when under
97 // the corresponding memory pressure.
98 enum : int { kNotificationIntervalPressureModerateMs = 5000 };
99 enum : int { kNotificationIntervalPressureCriticalMs = 1000 };
100
101 #if defined(MEMORY_PRESSURE_IS_POLLING)
102 // Fully configurable constructor for polling platforms.
103 MemoryPressureMonitor(const scoped_refptr<base::TaskRunner>& task_runner,
104 base::TickClock* tick_clock,
105 MemoryPressureStatsCollector* stats_collector,
106 MemoryPressureCalculator* calculator,
107 const DispatchCallback& dispatch_callback);
108 #else
109 // Constructor for non-polling platforms.
110 MemoryPressureMonitor(const scoped_refptr<base::TaskRunner>& task_runner,
111 base::TickClock* tick_clock,
112 MemoryPressureStatsCollector* stats_collector,
113 const DispatchCallback& dispatch_callback,
114 MemoryPressureLevel initial_pressure_level);
115 #endif
116
117 ~MemoryPressureMonitor();
118
119 // Returns the current memory pressure level. On polling platforms this may
120 // result in a forced calculation of the current pressure level (a cheap
121 // operation). Can be called from any thread.
122 MemoryPressureLevel GetCurrentPressureLevel();
123
124 // Schedules a memory pressure check to run soon. This can be called from any
125 // thread.
126 void CheckMemoryPressureSoon();
127
128 private:
129 // For unittesting.
130 friend class TestMemoryPressureMonitor;
131
132 #if !defined(MEMORY_PRESSURE_IS_POLLING)
133 // Notifications from the OS will be routed here by the contained
134 // MemoryPressureMonitorImpl instance. For statistics and renotification to
135 // work properly this must be notified of all pressure level changes, even
136 // those indicating a return to a state of no pressure.
137 void OnMemoryPressureChanged(MemoryPressureLevel level);
138 #endif
139
140 // Starts the memory pressure monitor. To be called in the constructor.
141 void Start();
142
143 // Checks memory pressure and updates stats. This is the entry point for all
144 // scheduled checks. Each scheduled check is assigned a |serial| id
145 // (monotonically increasing) which is used to tie the task to the time at
146 // which it was scheduled via the |scheduled_checks_| map.
147 void CheckPressureAndUpdateStats(int serial);
148 void CheckPressureAndUpdateStatsLocked(int serial);
149
150 // Ensures that a task is scheduled for renotification/recalculation/stats
151 // updating. Uses the |serial| id of the current task to determine the time at
152 // which the next scheduled check should run. Assumes |lock_| is held.
153 void ScheduleTaskIfNeededLocked(int serial);
154
155 // Schedules a task.
156 void ScheduleTaskLocked(base::TimeTicks when);
157
158 // A lock for synchronization.
159 base::Lock lock_;
160
161 // Injected dependencies.
162 // The task runner on which periodic pressure checks and statistics uploading
163 // are run.
164 scoped_refptr<base::TaskRunner> task_runner_;
165 // The tick clock in use. Used under |lock_|.
166 base::TickClock* tick_clock_;
167 // The stats collector in use. Used under |lock_|.
168 MemoryPressureStatsCollector* stats_collector_;
169 // The memory pressure calculator in use. Used under |lock_|.
170 MemoryPressureCalculator* calculator_;
171 // The dispatch callback to use.
172 DispatchCallback dispatch_callback_;
173
174 #if !defined(MEMORY_PRESSURE_IS_POLLING)
175 // On non-polling platforms this object is responsible for routing OS
176 // notifications to OnMemoryPressureChanged, and setting the initial pressure
177 // value. The OS specific implementation is responsible for allocating this
178 // object.
179 std::unique_ptr<MemoryPressureMonitorImpl> monitor_impl_;
180 #endif
181
182 // Object state.
183 // The pressure level as of the most recent poll or notification. Under
184 // |lock_|.
185 MemoryPressureLevel current_memory_pressure_level_;
186 #if defined(MEMORY_PRESSURE_IS_POLLING)
187 // Time of the last pressure check. Under |lock_|. Only needed for polling
188 // implementations.
189 base::TimeTicks last_check_;
190 #endif
191 // Time of the last pressure notification. Under |lock_|.
192 base::TimeTicks last_notification_;
193 // A map of scheduled pressure checks/statistics updates and their serial
194 // numbers. Under |lock_|.
195 std::map<int, base::TimeTicks> scheduled_checks_;
196 // The most recently assigned serial number for a pressure check. The number
197 // 0 will never be assigned but will instead be reserved for unscheduled
198 // checks initiated externally. Under |lock_|.
199 int serial_number_;
200
201 // Weak pointer factory to ourself used for posting delayed tasks to
202 // task_runner_.
203 base::WeakPtrFactory<MemoryPressureMonitor> weak_ptr_factory_;
204
205 DISALLOW_COPY_AND_ASSIGN(MemoryPressureMonitor);
206 };
207
208 } // namespace memory_pressure
209
210 #endif // COMPONENTS_MEMORY_PRESSURE_MEMORY_PRESSURE_MONITOR_H_
OLDNEW
« no previous file with comments | « components/memory_pressure/memory_pressure_listener.cc ('k') | components/memory_pressure/memory_pressure_monitor.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698