// 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/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() const 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_; // Weak pointer factory to ourself used for scheduling calls to // CheckMemoryPressure/CheckMemoryPressureAndRecordStatistics via |timer_|. base::WeakPtrFactory weak_ptr_factory_; DISALLOW_COPY_AND_ASSIGN(MemoryPressureMonitor); }; } // namespace win } // namespace base #endif // BASE_MEMORY_MEMORY_PRESSURE_MONITOR_WIN_H_