|  | // 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() const 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_ |