Commit fdbd4f0c authored by Sebastien Marchand's avatar Sebastien Marchand Committed by Commit Bot

Finch-Parametrize the Memory Pressure Monitor params.

This adds the feature flag for the new memory pressure monitor and
moves all the hardcoded parameters to base::FeatureParam so they can
be changed via Finch.

Bug: 771478
Change-Id: Ifcddff8ef66690ea93791bf6c2659373d696f7cb
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1542161
Commit-Queue: Sébastien Marchand <sebmarchand@chromium.org>
Reviewed-by: default avatarChris Hamilton <chrisha@chromium.org>
Cr-Commit-Position: refs/heads/master@{#654613}
parent cfe50db5
...@@ -12,6 +12,14 @@ ...@@ -12,6 +12,14 @@
#include "chrome/browser/memory/memory_pressure_monitor_win.h" #include "chrome/browser/memory/memory_pressure_monitor_win.h"
#endif #endif
namespace features {
// Enables the new memory pressure monitor.
const base::Feature kNewMemoryPressureMonitor{
"NewMemoryPressureMonitor", base::FEATURE_DISABLED_BY_DEFAULT};
} // namespace features
namespace memory { namespace memory {
namespace { namespace {
......
...@@ -7,10 +7,15 @@ ...@@ -7,10 +7,15 @@
#include <memory> #include <memory>
#include "base/feature_list.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/memory/memory_pressure_listener.h" #include "base/memory/memory_pressure_listener.h"
#include "base/sequence_checker.h" #include "base/sequence_checker.h"
namespace features {
extern const base::Feature kNewMemoryPressureMonitor;
}
namespace memory { namespace memory {
// The memory pressure monitor is responsible for monitoring some system metrics // The memory pressure monitor is responsible for monitoring some system metrics
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include <windows.h> #include <windows.h>
#include "base/logging.h" #include "base/logging.h"
#include "base/metrics/field_trial_params.h"
#include "base/time/time.h" #include "base/time/time.h"
namespace memory { namespace memory {
...@@ -17,22 +18,20 @@ using SamplingFrequency = performance_monitor::SystemMonitor::SamplingFrequency; ...@@ -17,22 +18,20 @@ using SamplingFrequency = performance_monitor::SystemMonitor::SamplingFrequency;
const DWORDLONG kMBBytes = 1024 * 1024; const DWORDLONG kMBBytes = 1024 * 1024;
// TODO(sebmarchand): Turn all these constants into base::FeatureParam and run
// some experiments to find the best values.
// Disk idle time is usually almost null (according to the // Disk idle time is usually almost null (according to the
// 'PerformanceMonitor.SystemMonitor.DiskIdleTime' metric) when the system is // 'PerformanceMonitor.SystemMonitor.DiskIdleTime' metric) when the system is
// under memory pressure, and it's usually at 100% the rest of the time. Using a // under memory pressure, and it's usually at 100% the rest of the time. Using a
// threshold of 30% should be a good indicator that there's a lot of I/O // threshold of 30% should be a good indicator that there's a lot of I/O
// activity that might be caused by memory pressure if the free physical memory // activity that might be caused by memory pressure if the free physical memory
// is low. // is low.
const float kDiskIdleTimeLowThreshold = 0.3; constexpr base::FeatureParam<double> kDiskIdleTimeLowThreshold{
&features::kNewMemoryPressureMonitor, "DiskIdleTimeThreshold", 0.3};
// A disk idle time observation window of 6 seconds combined with the threshold // A disk idle time observation window of 6 seconds combined with the threshold
// specified above should be sufficient to determine that there's a high and // specified above should be sufficient to determine that there's a high and
// sustained I/O activity. // sustained I/O activity.
constexpr base::TimeDelta kDiskIdleTimeWindowLength = static constexpr base::FeatureParam<int> kDiskIdleTimeWindowLengthSeconds{
base::TimeDelta::FromSeconds(6); &features::kNewMemoryPressureMonitor, "DiskIdleTimeWindowLengthSeconds", 6};
// A system is considered 'high memory' if it has more than 1.5GB of system // A system is considered 'high memory' if it has more than 1.5GB of system
// memory available for use by the memory manager (not reserved for hardware // memory available for use by the memory manager (not reserved for hardware
...@@ -49,28 +48,38 @@ const int kLargeMemoryThresholdMb = 1536; ...@@ -49,28 +48,38 @@ const int kLargeMemoryThresholdMb = 1536;
// available memory, paging until that is the case. To try to avoid paging a // available memory, paging until that is the case. To try to avoid paging a
// threshold slightly above this is chosen. The early threshold is slightly less // threshold slightly above this is chosen. The early threshold is slightly less
// grounded in reality and chosen as 2x critical. // grounded in reality and chosen as 2x critical.
const int kSmallMemoryDefaultEarlyThresholdMb = 600; static constexpr base::FeatureParam<int> kSmallMemoryDefaultEarlyThresholdMb{
const int kSmallMemoryDefaultCriticalThresholdMb = 300; &features::kNewMemoryPressureMonitor, "SmallMemoryDefaultEarlyThresholdMb",
600};
static constexpr base::FeatureParam<int> kSmallMemoryDefaultCriticalThresholdMb{
&features::kNewMemoryPressureMonitor,
"SmallMemoryDefaultCriticalThresholdMb", 300};
// These are the default thresholds used for systems with >= ~2GB of physical // These are the default thresholds used for systems with >= ~2GB of physical
// memory. Such systems have been observed to always maintain ~300MB of // memory. Such systems have been observed to always maintain ~300MB of
// available memory, paging until that is the case. // available memory, paging until that is the case.
const int kLargeMemoryDefaultEarlyThresholdMb = 1000; static constexpr base::FeatureParam<int> kLargeMemoryDefaultEarlyThresholdMb{
const int kLargeMemoryDefaultCriticalThresholdMb = 500; &features::kNewMemoryPressureMonitor, "LargeMemoryDefaultEarlyThresholdMb",
1000};
static constexpr base::FeatureParam<int> kLargeMemoryDefaultCriticalThresholdMb{
&features::kNewMemoryPressureMonitor,
"LargeMemoryDefaultCriticalThresholdMb", 500};
// A window length of 10 seconds should be sufficient to determine that the // A window length of 10 seconds should be sufficient to determine that the
// system is under pressure. A shorter window will lead to too many false // system is under pressure. A shorter window will lead to too many false
// positives (e.g. a brief memory spike will be treated as a memory pressure // positives (e.g. a brief memory spike will be treated as a memory pressure
// event) and a longer one will delay the response to memory pressure. // event) and a longer one will delay the response to memory pressure.
constexpr base::TimeDelta kFreeMemoryWindowLength = static constexpr base::FeatureParam<int> kFreeMemoryWindowLengthSeconds{
base::TimeDelta::FromSeconds(10); &features::kNewMemoryPressureMonitor, "FreeMemoryWindowLengthSeconds", 10};
// If 40% of the samples in the free physical memory observation window have a // If 40% of the samples in the free physical memory observation window have a
// value lower than one of the threshold then the window will consider that the // value lower than one of the threshold then the window will consider that the
// memory is under this limit. This makes this signal more stable if the memory // memory is under this limit. This makes this signal more stable if the memory
// varies a lot (which can happen if the system is actively trying to free some // varies a lot (which can happen if the system is actively trying to free some
// memory). // memory).
const float kFreeMemorySampleRatioToBePositive = 0.4; constexpr base::FeatureParam<double> kFreeMemorySampleRatioToBePositive{
&features::kNewMemoryPressureMonitor, "FreeMemorySampleRatioToBePositive",
0.4};
FreeMemoryObservationWindow::Config GetFreeMemoryWindowConfig() { FreeMemoryObservationWindow::Config GetFreeMemoryWindowConfig() {
// Default to a 'high' memory situation, which uses more conservative // Default to a 'high' memory situation, which uses more conservative
...@@ -84,28 +93,31 @@ FreeMemoryObservationWindow::Config GetFreeMemoryWindowConfig() { ...@@ -84,28 +93,31 @@ FreeMemoryObservationWindow::Config GetFreeMemoryWindowConfig() {
high_memory = mem_status.ullTotalPhys >= kLargeMemoryThresholdBytes; high_memory = mem_status.ullTotalPhys >= kLargeMemoryThresholdBytes;
} }
int low_memory_early_limit_mb = kSmallMemoryDefaultEarlyThresholdMb; int low_memory_early_limit_mb = kSmallMemoryDefaultEarlyThresholdMb.Get();
int low_memory_critical_limit_mb = kSmallMemoryDefaultCriticalThresholdMb; int low_memory_critical_limit_mb =
kSmallMemoryDefaultCriticalThresholdMb.Get();
if (high_memory) { if (high_memory) {
low_memory_early_limit_mb = kLargeMemoryDefaultEarlyThresholdMb; low_memory_early_limit_mb = kLargeMemoryDefaultEarlyThresholdMb.Get();
low_memory_critical_limit_mb = kLargeMemoryDefaultCriticalThresholdMb; low_memory_critical_limit_mb = kLargeMemoryDefaultCriticalThresholdMb.Get();
} }
return { return {
.low_memory_early_limit_mb = low_memory_early_limit_mb, .low_memory_early_limit_mb = low_memory_early_limit_mb,
.low_memory_critical_limit_mb = low_memory_critical_limit_mb, .low_memory_critical_limit_mb = low_memory_critical_limit_mb,
.sample_ratio_to_be_positive = kFreeMemorySampleRatioToBePositive, .sample_ratio_to_be_positive = kFreeMemorySampleRatioToBePositive.Get(),
}; };
} }
} // namespace } // namespace
MemoryPressureMonitorWin::MemoryPressureMonitorWin() MemoryPressureMonitorWin::MemoryPressureMonitorWin()
: free_memory_obs_window_(kFreeMemoryWindowLength, : free_memory_obs_window_(
GetFreeMemoryWindowConfig()), base::TimeDelta::FromSeconds(kFreeMemoryWindowLengthSeconds.Get()),
disk_idle_time_obs_window_(kDiskIdleTimeWindowLength, GetFreeMemoryWindowConfig()),
kDiskIdleTimeLowThreshold) { disk_idle_time_obs_window_(
base::TimeDelta::FromSeconds(kDiskIdleTimeWindowLengthSeconds.Get()),
kDiskIdleTimeLowThreshold.Get()) {
// The amount of free memory is always tracked. // The amount of free memory is always tracked.
refresh_frequencies_ = { refresh_frequencies_ = {
.free_phys_memory_mb_frequency = SamplingFrequency::kDefaultFrequency, .free_phys_memory_mb_frequency = SamplingFrequency::kDefaultFrequency,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment