0

Adding flag to specify the used memory pressure strategy

This CL adds a flag to change the memory pressure event thresholds. This flag will later on then used in a finch experiment to test the influence of the thresholds on the system.

BUG=449374
TEST=-

Review URL: https://codereview.chromium.org/803443006

Cr-Commit-Position: refs/heads/master@{#312499}
This commit is contained in:
skuhne
2015-01-21 16:05:34 -08:00
committed by Commit bot
parent 2f12f2dbd9
commit f6f74b0eee
9 changed files with 146 additions and 13 deletions

@ -24,25 +24,56 @@ const int kModerateMemoryPressureCooldown =
kModerateMemoryPressureCooldownMs / kMemoryPressureIntervalMs;
// Threshold constants to emit pressure events.
const int kMemoryPressureModerateThresholdPercent = 70;
const int kMemoryPressureCriticalThresholdPercent = 90;
const int kNormalMemoryPressureModerateThresholdPercent = 60;
const int kNormalMemoryPressureCriticalThresholdPercent = 90;
const int kAggressiveMemoryPressureModerateThresholdPercent = 35;
const int kAggressiveMemoryPressureCriticalThresholdPercent = 70;
// Converts a |MemoryPressureThreshold| value into a used memory percentage for
// the moderate pressure event.
int GetModerateMemoryThresholdInPercent(
MemoryPressureObserverChromeOS::MemoryPressureThresholds thresholds) {
return thresholds == MemoryPressureObserverChromeOS::
THRESHOLD_AGGRESSIVE_CACHE_DISCARD ||
thresholds == MemoryPressureObserverChromeOS::THRESHOLD_AGGRESSIVE
? kAggressiveMemoryPressureModerateThresholdPercent
: kNormalMemoryPressureModerateThresholdPercent;
}
// Converts a |MemoryPressureThreshold| value into a used memory percentage for
// the critical pressure event.
int GetCriticalMemoryThresholdInPercent(
MemoryPressureObserverChromeOS::MemoryPressureThresholds thresholds) {
return thresholds == MemoryPressureObserverChromeOS::
THRESHOLD_AGGRESSIVE_TAB_DISCARD ||
thresholds == MemoryPressureObserverChromeOS::THRESHOLD_AGGRESSIVE
? kAggressiveMemoryPressureCriticalThresholdPercent
: kNormalMemoryPressureCriticalThresholdPercent;
}
// Converts free percent of memory into a memory pressure value.
MemoryPressureListener::MemoryPressureLevel GetMemoryPressureLevelFromFillLevel(
int memory_fill_level) {
if (memory_fill_level < kMemoryPressureModerateThresholdPercent)
int actual_fill_level,
int moderate_threshold,
int critical_threshold) {
if (actual_fill_level < moderate_threshold)
return MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE;
return memory_fill_level < kMemoryPressureCriticalThresholdPercent ?
MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE :
MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL;
return actual_fill_level < critical_threshold
? MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE
: MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL;
}
} // namespace
MemoryPressureObserverChromeOS::MemoryPressureObserverChromeOS()
MemoryPressureObserverChromeOS::MemoryPressureObserverChromeOS(
MemoryPressureThresholds thresholds)
: current_memory_pressure_level_(
MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE),
MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE),
moderate_pressure_repeat_count_(0),
moderate_pressure_threshold_percent_(
GetModerateMemoryThresholdInPercent(thresholds)),
critical_pressure_threshold_percent_(
GetCriticalMemoryThresholdInPercent(thresholds)),
weak_ptr_factory_(this) {
StartObserving();
}
@ -74,7 +105,9 @@ void MemoryPressureObserverChromeOS::CheckMemoryPressure() {
MemoryPressureListener::MemoryPressureLevel old_pressure =
current_memory_pressure_level_;
current_memory_pressure_level_ =
GetMemoryPressureLevelFromFillLevel(GetUsedMemoryInPercent());
GetMemoryPressureLevelFromFillLevel(GetUsedMemoryInPercent(),
moderate_pressure_threshold_percent_,
critical_pressure_threshold_percent_);
// In case there is no memory pressure we do not notify.
if (current_memory_pressure_level_ ==
MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE) {

@ -27,7 +27,27 @@ class BASE_EXPORT MemoryPressureObserverChromeOS {
public:
using GetUsedMemoryInPercentCallback = int (*)();
MemoryPressureObserverChromeOS();
// There are two memory pressure events:
// MODERATE - which will mainly release caches.
// CRITICAL - which will discard tabs.
// The |MemoryPressureThresholds| enum selects the strategy of firing these
// events: A conservative strategy will keep as much content in memory as
// possible (causing the system to swap to zram) and an aggressive strategy
// will release memory earlier to avoid swapping.
enum MemoryPressureThresholds {
// Use the system default.
THRESHOLD_DEFAULT = 0,
// Try to keep as much content in memory as possible.
THRESHOLD_CONSERVATIVE = 1,
// Discard caches earlier, allowing to keep more tabs in memory.
THRESHOLD_AGGRESSIVE_CACHE_DISCARD = 2,
// Discard tabs earlier, allowing the system to get faster.
THRESHOLD_AGGRESSIVE_TAB_DISCARD = 3,
// Discard caches and tabs earlier to allow the system to be faster.
THRESHOLD_AGGRESSIVE = 4
};
explicit MemoryPressureObserverChromeOS(MemoryPressureThresholds thresholds);
virtual ~MemoryPressureObserverChromeOS();
// Redo the memory pressure calculation soon and call again if a critical
@ -71,6 +91,10 @@ class BASE_EXPORT MemoryPressureObserverChromeOS {
// gets used to count the number of events since the last event occured.
int moderate_pressure_repeat_count_;
// The thresholds for moderate and critical pressure.
const int moderate_pressure_threshold_percent_;
const int critical_pressure_threshold_percent_;
base::WeakPtrFactory<MemoryPressureObserverChromeOS> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(MemoryPressureObserverChromeOS);

@ -42,7 +42,10 @@ bool WasOnMemoryPressureCalled() {
class TestMemoryPressureObserver : public MemoryPressureObserverChromeOS {
public:
TestMemoryPressureObserver() : memory_in_percent_override_(0) {
TestMemoryPressureObserver() :
MemoryPressureObserverChromeOS(
MemoryPressureObserverChromeOS::THRESHOLD_DEFAULT),
memory_in_percent_override_(0) {
// Disable any timers which are going on and set a special memory reporting
// function.
StopObserving();

@ -1129,6 +1129,24 @@ Press any key to continue exploring.
<message name="IDS_FLAGS_DISABLE_MEMORY_PRESSURE_DESCRIPTION" desc="Description for the flag to disable memory pressure handling on ChromeOS.">
Disable enhanced memory pressure handling on ChromeOS.
</message>
<message name="IDS_FLAGS_MEMORY_PRESSURE_THRESHOLD_NAME" desc="Name for the flag which specifies which memory pressure strategy should be used on ChromeOS.">
Memory discard strategy for advanced pressure handling
</message>
<message name="IDS_FLAGS_MEMORY_PRESSURE_THRESHOLD_DESCRIPTION" desc="Description for the flag which specifies which memory pressure strategy should be used on ChromeOS.">
Memory discarding strategy to use
</message>
<message name="IDS_FLAGS_CONSERVATIVE_THRESHOLDS" desc="The value of the Memory pressure for ChromeOS which requests conservative thresholds.">
Conservative memory pressure release strategy
</message>
<message name="IDS_FLAGS_AGGRESSIVE_CACHE_DISCARD_THRESHOLDS" desc="The value of the Memory pressure thresholds for ChromeOS which use an aggressive cache release strategy.">
Aggressive cache release strategy
</message>
<message name="IDS_FLAGS_AGGRESSIVE_TAB_DISCARD_THRESHOLDS" desc="The value of the Memory pressure thresholds for ChromeOS which uses an aggressive tab release strategy.">
Aggressive tab release strategy
</message>
<message name="IDS_FLAGS_AGGRESSIVE_THRESHOLDS" desc="The value of the Memory pressure thresholds for ChromeOS which use an aggressive release strategy.">
Aggressive tab and cache release strategy
</message>
<message name="IDS_FLAGS_WAKE_ON_PACKETS_NAME" desc="Name for the flag to enable wake on packets.">
Wake On Packets
</message>

@ -284,6 +284,20 @@ const Experiment::Choice kEnableGpuRasterizationChoices[] = {
switches::kForceGpuRasterization, "" },
};
#if defined(OS_CHROMEOS)
const Experiment::Choice kMemoryPressureThresholdChoices[] = {
{ IDS_GENERIC_EXPERIMENT_CHOICE_DEFAULT, "", "" },
{ IDS_FLAGS_CONSERVATIVE_THRESHOLDS,
chromeos::switches::kMemoryPressureThresholds, "1" },
{ IDS_FLAGS_AGGRESSIVE_CACHE_DISCARD_THRESHOLDS,
chromeos::switches::kMemoryPressureThresholds, "2" },
{ IDS_FLAGS_AGGRESSIVE_TAB_DISCARD_THRESHOLDS,
chromeos::switches::kMemoryPressureThresholds, "3" },
{ IDS_FLAGS_AGGRESSIVE_THRESHOLDS,
chromeos::switches::kMemoryPressureThresholds, "4" },
};
#endif
// We're using independent flags here (as opposed to a common flag with
// different values) to be able to enable/disable the entire experience
// associated with this feature server-side from the FieldTrial (the complete
@ -2002,6 +2016,13 @@ const Experiment kExperiments[] = {
kOsCrOS,
SINGLE_VALUE_TYPE(chromeos::switches::kDisableMemoryPressureSystemChromeOS)
},
{
"memory-pressure-thresholds",
IDS_FLAGS_MEMORY_PRESSURE_THRESHOLD_NAME,
IDS_FLAGS_MEMORY_PRESSURE_THRESHOLD_DESCRIPTION,
kOsCrOS,
MULTI_VALUE_TYPE(kMemoryPressureThresholdChoices)
},
{
"wake-on-packets",
IDS_FLAGS_WAKE_ON_PACKETS_NAME,

@ -213,6 +213,10 @@ const char kLoginProfile[] = "login-profile";
// Specifies the user which is already logged in.
const char kLoginUser[] = "login-user";
// The memory pressure thresholds selection which is used to decide when a
// memory pressure event needs to get fired.
const char kMemoryPressureThresholds[] = "memory-pressure-thresholds";
// Enables natural scroll by default.
const char kNaturalScrollDefault[] = "enable-natural-scroll-default";
@ -292,5 +296,28 @@ bool WakeOnWifiEnabled() {
return !base::CommandLine::ForCurrentProcess()->HasSwitch(kDisableWakeOnWifi);
}
base::MemoryPressureObserverChromeOS::MemoryPressureThresholds
GetMemoryPressureThresholds() {
if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
kMemoryPressureThresholds)) {
return base::MemoryPressureObserverChromeOS::THRESHOLD_DEFAULT;
}
const std::string option =
base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
kMemoryPressureThresholds);
if (option == "1") {
return base::MemoryPressureObserverChromeOS::THRESHOLD_CONSERVATIVE;
}
if (option == "2") {
return base::MemoryPressureObserverChromeOS::
THRESHOLD_AGGRESSIVE_CACHE_DISCARD;
}
if (option == "3") {
return base::MemoryPressureObserverChromeOS::
THRESHOLD_AGGRESSIVE_TAB_DISCARD;
}
return base::MemoryPressureObserverChromeOS::THRESHOLD_AGGRESSIVE;
}
} // namespace switches
} // namespace chromeos

@ -5,6 +5,7 @@
#ifndef CHROMEOS_CHROMEOS_SWITCHES_H_
#define CHROMEOS_CHROMEOS_SWITCHES_H_
#include "base/chromeos/memory_pressure_observer_chromeos.h"
#include "chromeos/chromeos_export.h"
namespace chromeos {
@ -82,6 +83,7 @@ CHROMEOS_EXPORT extern const char kIgnoreUserProfileMappingForTests[];
CHROMEOS_EXPORT extern const char kLoginManager[];
CHROMEOS_EXPORT extern const char kLoginProfile[];
CHROMEOS_EXPORT extern const char kLoginUser[];
CHROMEOS_EXPORT extern const char kMemoryPressureThresholds[];
CHROMEOS_EXPORT extern const char kNaturalScrollDefault[];
CHROMEOS_EXPORT extern const char kOobeGuestSession[];
CHROMEOS_EXPORT extern const char kOobeSkipPostLogin[];
@ -97,6 +99,9 @@ CHROMEOS_EXPORT extern const char kEnableCaptivePortalBypassProxy[];
CHROMEOS_EXPORT bool WakeOnWifiEnabled();
CHROMEOS_EXPORT base::MemoryPressureObserverChromeOS::MemoryPressureThresholds
GetMemoryPressureThresholds();
} // namespace switches
} // namespace chromeos

@ -490,7 +490,8 @@ void BrowserMainLoop::MainMessageLoopStart() {
#if defined(OS_CHROMEOS)
if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
chromeos::switches::kDisableMemoryPressureSystemChromeOS)) {
memory_pressure_observer_.reset(new base::MemoryPressureObserverChromeOS);
memory_pressure_observer_.reset(new base::MemoryPressureObserverChromeOS(
chromeos::switches::GetMemoryPressureThresholds()));
}
#endif

@ -50408,6 +50408,7 @@ To add a new entry, add it with any value and run test to compute valid value.
<int value="121858954" label="enable-supervised-user-safesites"/>
<int value="125934378" label="enable-password-link"/>
<int value="147373243" label="enable-deferred-image-decoding"/>
<int value="180074362" label="memory-pressure-thresholds"/>
<int value="203776499" label="enable-virtual-keyboard-overscroll"/>
<int value="270267831" label="enable-scripts-require-action"/>
<int value="278756320" label="disable-app-list-app-info"/>