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_
|