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..4da7d24bfdb75a38bb9be99b5877819b8c5ed3bf 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,21 +12,99 @@ namespace base { |
namespace { |
-// The time between memory pressure checks. |
-const int kMemoryPressureIntervalInMS = 1000; |
+// The time between memory pressure checks. While under critical pressure, this |
+// is also the timer to repeat cleanup attempts. |
+const int kMemoryPressureIntervalMs = 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 / kMemoryPressureIntervalMs; |
+ |
+// 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; |
} |
+} // namespace |
+ |
+MemoryPressureObserverChromeOS::MemoryPressureObserverChromeOS() |
+ : current_memory_pressure_level_( |
+ MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE), |
+ moderate_pressure_repeat_count_(0), |
+ weak_ptr_factory_(this) { |
+ StartObserving(); |
+} |
+ |
+MemoryPressureObserverChromeOS::~MemoryPressureObserverChromeOS() { |
+ StopObserving(); |
+} |
+ |
+void MemoryPressureObserverChromeOS::ScheduleEarlyCheck() { |
+ MessageLoop::current()->PostTask( |
+ FROM_HERE, |
+ Bind(&MemoryPressureObserverChromeOS::CheckMemoryPressure, |
+ weak_ptr_factory_.GetWeakPtr())); |
+} |
+ |
+void MemoryPressureObserverChromeOS::StartObserving() { |
+ timer_.Start(FROM_HERE, |
+ TimeDelta::FromMilliseconds(kMemoryPressureIntervalMs), |
+ Bind(&MemoryPressureObserverChromeOS::CheckMemoryPressure, |
+ weak_ptr_factory_.GetWeakPtr())); |
+} |
+ |
+void MemoryPressureObserverChromeOS::StopObserving() { |
+ // If StartObserving failed, StopObserving will still get called. |
+ timer_.Stop(); |
+} |
+ |
+void MemoryPressureObserverChromeOS::CheckMemoryPressure() { |
+ MemoryPressureListener::MemoryPressureLevel old_pressure = |
+ current_memory_pressure_level_; |
+ current_memory_pressure_level_ = |
+ GetMemoryPressureLevelFromFillLevel(GetUsedMemoryInPercent()); |
+ // In case 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_); |
+} |
+ |
// Gets the used ChromeOS memory in percent. |
-int GetUsedMemoryInPercent() { |
+int MemoryPressureObserverChromeOS::GetUsedMemoryInPercent() { |
base::SystemMemoryInfoKB info; |
if (!base::GetSystemMemoryInfo(&info)) { |
VLOG(1) << "Cannot determine the free memory of the system."; |
@@ -62,41 +141,4 @@ int GetUsedMemoryInPercent() { |
return percentage; |
} |
-} // namespace |
- |
-MemoryPressureObserverChromeOS::MemoryPressureObserverChromeOS() |
- : current_memory_pressure_level_( |
- MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE) { |
- StartObserving(); |
-} |
- |
-MemoryPressureObserverChromeOS::~MemoryPressureObserverChromeOS() { |
- StopObserving(); |
-} |
- |
-void MemoryPressureObserverChromeOS::StartObserving() { |
- timer_.Start(FROM_HERE, |
- base::TimeDelta::FromMilliseconds(kMemoryPressureIntervalInMS), |
- base::Bind(&MemoryPressureObserverChromeOS::CheckMemoryPressure, |
- base::Unretained(this))); |
-} |
- |
-void MemoryPressureObserverChromeOS::StopObserving() { |
- // If StartObserving failed, StopObserving will still get called. |
- timer_.Stop(); |
-} |
- |
-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); |
- } |
-} |
- |
} // namespace base |