| Index: base/chromeos/memory_pressure_observer_chromeos.cc
|
| diff --git a/base/chromeos/memory_pressure_observer_chromeos.cc b/base/chromeos/memory_pressure_observer_chromeos.cc
|
| index 22291da09ba9191054f26eb3c8bce70470917389..d7eae8ddea76556c40439709e727a20ad7605882 100644
|
| --- a/base/chromeos/memory_pressure_observer_chromeos.cc
|
| +++ b/base/chromeos/memory_pressure_observer_chromeos.cc
|
| @@ -4,6 +4,7 @@
|
|
|
| #include "base/chromeos/memory_pressure_observer_chromeos.h"
|
|
|
| +#include "base/message_loop/message_loop.h"
|
| #include "base/process/process_metrics.h"
|
| #include "base/time/time.h"
|
|
|
| @@ -11,15 +12,27 @@ namespace base {
|
|
|
| namespace {
|
|
|
| -// The time between memory pressure checks.
|
| +// The time between memory pressure checks. While under critical pressure, this
|
| +// is also the timer to repeat cleanup attempts.
|
| const int kMemoryPressureIntervalInMS = 1000;
|
|
|
| +// The time which should pass between two moderate memory pressure calls.
|
| +const int kModerateMemoryPressureCooldownMs = 10000;
|
| +
|
| +// Number of event polls before the next moderate pressure event can be sent.
|
| +const int kModerateMemoryPressureCooldown =
|
| + kModerateMemoryPressureCooldownMs / kMemoryPressureIntervalInMS;
|
| +
|
| +// Threshold constants to emit pressure events.
|
| +const int kMemoryPressureModerateThresholdPercent = 70;
|
| +const int kMemoryPressureCriticalThresholdPercent = 90;
|
| +
|
| // Converts free percent of memory into a memory pressure value.
|
| MemoryPressureListener::MemoryPressureLevel GetMemoryPressureLevelFromFillLevel(
|
| int memory_fill_level) {
|
| - if (memory_fill_level < 70)
|
| + if (memory_fill_level < kMemoryPressureModerateThresholdPercent)
|
| return MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE;
|
| - return memory_fill_level < 90 ?
|
| + return memory_fill_level < kMemoryPressureCriticalThresholdPercent ?
|
| MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE :
|
| MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL;
|
| }
|
| @@ -66,7 +79,10 @@ int GetUsedMemoryInPercent() {
|
|
|
| MemoryPressureObserverChromeOS::MemoryPressureObserverChromeOS()
|
| : current_memory_pressure_level_(
|
| - MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE) {
|
| + MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE),
|
| + used_memory_in_percent_(GetUsedMemoryInPercent),
|
| + moderate_pressure_repeat_count_(0),
|
| + weak_ptr_factory_(this) {
|
| StartObserving();
|
| }
|
|
|
| @@ -74,11 +90,25 @@ MemoryPressureObserverChromeOS::~MemoryPressureObserverChromeOS() {
|
| StopObserving();
|
| }
|
|
|
| +void MemoryPressureObserverChromeOS::ScheduleEarlyCheck() {
|
| + MessageLoop::current()->PostTask(
|
| + FROM_HERE,
|
| + Bind(&MemoryPressureObserverChromeOS::CheckMemoryPressure,
|
| + weak_ptr_factory_.GetWeakPtr()));
|
| +}
|
| +
|
| +void
|
| +MemoryPressureObserverChromeOS::SetGetUsedMemoryInPercentCallbackForUnittest(
|
| + MemoryPressureObserverChromeOS::GetUsedMemoryInPercentCallback callback) {
|
| + DCHECK(callback);
|
| + used_memory_in_percent_ = callback;
|
| +}
|
| +
|
| void MemoryPressureObserverChromeOS::StartObserving() {
|
| timer_.Start(FROM_HERE,
|
| - base::TimeDelta::FromMilliseconds(kMemoryPressureIntervalInMS),
|
| - base::Bind(&MemoryPressureObserverChromeOS::CheckMemoryPressure,
|
| - base::Unretained(this)));
|
| + TimeDelta::FromMilliseconds(kMemoryPressureIntervalInMS),
|
| + Bind(&MemoryPressureObserverChromeOS::CheckMemoryPressure,
|
| + weak_ptr_factory_.GetWeakPtr()));
|
| }
|
|
|
| void MemoryPressureObserverChromeOS::StopObserving() {
|
| @@ -89,14 +119,34 @@ void MemoryPressureObserverChromeOS::StopObserving() {
|
| void MemoryPressureObserverChromeOS::CheckMemoryPressure() {
|
| MemoryPressureListener::MemoryPressureLevel old_pressure =
|
| current_memory_pressure_level_;
|
| - MemoryPressureListener::MemoryPressureLevel new_pressure =
|
| - GetMemoryPressureLevelFromFillLevel(GetUsedMemoryInPercent());
|
| - if (old_pressure != new_pressure) {
|
| - current_memory_pressure_level_ = new_pressure;
|
| - // Everything but NONE will be sent to the listener.
|
| - if (new_pressure != MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE)
|
| - MemoryPressureListener::NotifyMemoryPressure(new_pressure);
|
| + current_memory_pressure_level_ =
|
| + GetMemoryPressureLevelFromFillLevel(used_memory_in_percent_());
|
| + // In cas there is no memory pressure we do not notify.
|
| + if (current_memory_pressure_level_ ==
|
| + MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE) {
|
| + return;
|
| + }
|
| + if (old_pressure == current_memory_pressure_level_) {
|
| + // If the memory pressure is still at the same level, we notify again for a
|
| + // critical level. In case of a moderate level repeat however, we only send
|
| + // a notification after a certain time has passed.
|
| + if (current_memory_pressure_level_ ==
|
| + MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE &&
|
| + ++moderate_pressure_repeat_count_ <
|
| + kModerateMemoryPressureCooldown) {
|
| + return;
|
| + }
|
| + } else if (current_memory_pressure_level_ ==
|
| + MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE &&
|
| + old_pressure ==
|
| + MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL) {
|
| + // When we reducing the pressure level from critical to moderate, we
|
| + // restart the timeout and do not send another notification.
|
| + moderate_pressure_repeat_count_ = 0;
|
| + return;
|
| }
|
| + moderate_pressure_repeat_count_ = 0;
|
| + MemoryPressureListener::NotifyMemoryPressure(current_memory_pressure_level_);
|
| }
|
|
|
| } // namespace base
|
|
|