forked from chromium/chromium
-
Notifications
You must be signed in to change notification settings - Fork 0
/
memory_pressure_monitor_win.h
148 lines (115 loc) · 6.1 KB
/
memory_pressure_monitor_win.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef BASE_MEMORY_MEMORY_PRESSURE_MONITOR_WIN_H_
#define BASE_MEMORY_MEMORY_PRESSURE_MONITOR_WIN_H_
#include "base/base_export.h"
#include "base/macros.h"
#include "base/memory/memory_pressure_listener.h"
#include "base/memory/memory_pressure_monitor.h"
#include "base/memory/weak_ptr.h"
#include "base/threading/thread_checker.h"
#include "base/timer/timer.h"
// To not pull in windows.h.
typedef struct _MEMORYSTATUSEX MEMORYSTATUSEX;
namespace base {
namespace win {
// Windows memory pressure monitor. Because there is no OS provided signal this
// polls at a low frequency (once per second), and applies internal hysteresis.
class BASE_EXPORT MemoryPressureMonitor : public base::MemoryPressureMonitor {
public:
// Constants governing the polling and hysteresis behaviour of the observer.
// The polling interval, in milliseconds. While under critical pressure, this
// is also the timer to repeat cleanup attempts.
static const int kPollingIntervalMs;
// The time which should pass between 2 successive moderate memory pressure
// signals, in milliseconds.
static const int kModeratePressureCooldownMs;
// The number of cycles that should pass between 2 successive moderate memory
// pressure signals.
static const int kModeratePressureCooldownCycles;
// Constants governing the memory pressure level detection.
// The amount of total system memory beyond which a system is considered to be
// a large-memory system.
static const int kLargeMemoryThresholdMb;
// Default minimum free memory thresholds for small-memory systems, in MB.
static const int kSmallMemoryDefaultModerateThresholdMb;
static const int kSmallMemoryDefaultCriticalThresholdMb;
// Default minimum free memory thresholds for large-memory systems, in MB.
static const int kLargeMemoryDefaultModerateThresholdMb;
static const int kLargeMemoryDefaultCriticalThresholdMb;
// Default constructor. Will choose thresholds automatically basd on the
// actual amount of system memory.
MemoryPressureMonitor();
// Constructor with explicit memory thresholds. These represent the amount of
// free memory below which the applicable memory pressure state engages.
MemoryPressureMonitor(int moderate_threshold_mb, int critical_threshold_mb);
~MemoryPressureMonitor() override;
// Schedules a memory pressure check to run soon. This must be called on the
// same thread where the monitor was instantiated.
void CheckMemoryPressureSoon();
// Get the current memory pressure level. This can be called from any thread.
MemoryPressureLevel GetCurrentPressureLevel() override;
void SetDispatchCallback(const DispatchCallback& callback) override;
// Returns the moderate pressure level free memory threshold, in MB.
int moderate_threshold_mb() const { return moderate_threshold_mb_; }
// Returns the critical pressure level free memory threshold, in MB.
int critical_threshold_mb() const { return critical_threshold_mb_; }
protected:
// Internals are exposed for unittests.
// Automatically infers threshold values based on system memory. This invokes
// GetMemoryStatus so it can be mocked in unittests.
void InferThresholds();
// Starts observing the memory fill level. Calls to StartObserving should
// always be matched with calls to StopObserving.
void StartObserving();
// Stop observing the memory fill level. May be safely called if
// StartObserving has not been called. Must be called from the same thread on
// which the monitor was instantiated.
void StopObserving();
// Checks memory pressure, storing the current level, applying any hysteresis
// and emitting memory pressure level change signals as necessary. This
// function is called periodically while the monitor is observing memory
// pressure. This is split out from CheckMemoryPressureAndRecordStatistics so
// that it may be called by CheckMemoryPressureSoon and not invoke UMA
// logging. Must be called from the same thread on which the monitor was
// instantiated.
void CheckMemoryPressure();
// Wrapper to CheckMemoryPressure that also records the observed memory
// pressure level via an UMA enumeration. This is the function that is called
// periodically by the timer. Must be called from the same thread on which the
// monitor was instantiated.
void CheckMemoryPressureAndRecordStatistics();
// Calculates the current instantaneous memory pressure level. This does not
// use any hysteresis and simply returns the result at the current moment. Can
// be called on any thread.
MemoryPressureLevel CalculateCurrentPressureLevel();
// Gets system memory status. This is virtual as a unittesting hook. Returns
// true if the system call succeeds, false otherwise. Can be called on any
// thread.
virtual bool GetSystemMemoryStatus(MEMORYSTATUSEX* mem_status);
private:
// Threshold amounts of available memory that trigger pressure levels. See
// memory_pressure_monitor.cc for a discussion of reasonable values for these.
int moderate_threshold_mb_;
int critical_threshold_mb_;
// A periodic timer to check for memory pressure changes.
base::RepeatingTimer timer_;
// The current memory pressure.
MemoryPressureLevel current_memory_pressure_level_;
// To slow down the amount of moderate pressure event calls, this gets used to
// count the number of events since the last event occured. This is used by
// |CheckMemoryPressure| to apply hysteresis on the raw results of
// |CalculateCurrentPressureLevel|.
int moderate_pressure_repeat_count_;
// Ensures that this object is used from a single thread.
base::ThreadChecker thread_checker_;
DispatchCallback dispatch_callback_;
// Weak pointer factory to ourself used for scheduling calls to
// CheckMemoryPressure/CheckMemoryPressureAndRecordStatistics via |timer_|.
base::WeakPtrFactory<MemoryPressureMonitor> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(MemoryPressureMonitor);
};
} // namespace win
} // namespace base
#endif // BASE_MEMORY_MEMORY_PRESSURE_MONITOR_WIN_H_