Index: content/browser/renderer_host/renderer_frame_manager.cc |
diff --git a/content/browser/renderer_host/renderer_frame_manager.cc b/content/browser/renderer_host/renderer_frame_manager.cc |
index 1eff47d67da952fffeb99c36110470cc732fd921..a05a92c3f59c595f9cec9808ebb7946e4001f4d5 100644 |
--- a/content/browser/renderer_host/renderer_frame_manager.cc |
+++ b/content/browser/renderer_host/renderer_frame_manager.cc |
@@ -8,12 +8,15 @@ |
#include "base/bind.h" |
#include "base/logging.h" |
+#include "base/memory/memory_coordinator_client_registry.h" |
+#include "base/memory/memory_coordinator_proxy.h" |
#include "base/memory/memory_pressure_listener.h" |
#include "base/memory/memory_pressure_monitor.h" |
#include "base/memory/shared_memory.h" |
#include "base/sys_info.h" |
#include "build/build_config.h" |
#include "content/common/host_shared_bitmap_manager.h" |
+#include "content/public/common/content_features.h" |
namespace content { |
namespace { |
@@ -72,35 +75,50 @@ void RendererFrameManager::UnlockFrame(RendererFrameManagerClient* frame) { |
} |
size_t RendererFrameManager::GetMaxNumberOfSavedFrames() const { |
- base::MemoryPressureMonitor* monitor = base::MemoryPressureMonitor::Get(); |
- |
- if (!monitor) |
- return max_number_of_saved_frames_; |
- |
- // Until we have a global OnMemoryPressureChanged event we need to query the |
- // value from our specific pressure monitor. |
int percentage = 100; |
- switch (monitor->GetCurrentPressureLevel()) { |
- case base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE: |
- percentage = 100; |
- break; |
- case base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE: |
- percentage = kModeratePressurePercentage; |
- break; |
- case base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL: |
- percentage = kCriticalPressurePercentage; |
- break; |
+ if (base::FeatureList::IsEnabled(features::kMemoryCoordinator)) { |
+ switch (base::MemoryCoordinatorProxy::GetInstance()-> |
+ GetCurrentMemoryState()) { |
+ case base::MemoryState::NORMAL: |
+ percentage = 100; |
+ break; |
+ case base::MemoryState::THROTTLED: |
+ percentage = kCriticalPressurePercentage; |
+ break; |
+ case base::MemoryState::SUSPENDED: |
+ case base::MemoryState::UNKNOWN: |
+ NOTREACHED(); |
+ break; |
+ } |
+ } else { |
+ base::MemoryPressureMonitor* monitor = base::MemoryPressureMonitor::Get(); |
+ |
+ if (!monitor) |
+ return max_number_of_saved_frames_; |
+ |
+ // Until we have a global OnMemoryPressureChanged event we need to query the |
+ // value from our specific pressure monitor. |
+ switch (monitor->GetCurrentPressureLevel()) { |
+ case base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE: |
+ percentage = 100; |
+ break; |
+ case base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE: |
+ percentage = kModeratePressurePercentage; |
+ break; |
+ case base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL: |
+ percentage = kCriticalPressurePercentage; |
+ break; |
+ } |
} |
size_t frames = (max_number_of_saved_frames_ * percentage) / 100; |
return std::max(static_cast<size_t>(1), frames); |
} |
RendererFrameManager::RendererFrameManager() |
- : memory_pressure_listener_( |
+ : memory_pressure_listener_(new base::MemoryPressureListener( |
base::Bind(&RendererFrameManager::OnMemoryPressure, |
- base::Unretained(this))) { |
- // Note: With the destruction of this class the |memory_pressure_listener_| |
- // gets destroyed and the observer will remove itself. |
+ base::Unretained(this)))) { |
+ base::MemoryCoordinatorClientRegistry::GetInstance()->Register(this); |
max_number_of_saved_frames_ = |
#if defined(OS_ANDROID) |
// If the amount of memory on the device is >= 3.5 GB, save up to 5 |
@@ -136,21 +154,40 @@ void RendererFrameManager::CullUnlockedFrames(size_t saved_frame_limit) { |
void RendererFrameManager::OnMemoryPressure( |
base::MemoryPressureListener::MemoryPressureLevel memory_pressure_level) { |
- int saved_frame_limit = max_number_of_saved_frames_; |
- if (saved_frame_limit <= 1) |
- return; |
- int percentage = 100; |
switch (memory_pressure_level) { |
case base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE: |
- percentage = kModeratePressurePercentage; |
+ PurgeMemory(kModeratePressurePercentage); |
break; |
case base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL: |
- percentage = kCriticalPressurePercentage; |
+ PurgeMemory(kCriticalPressurePercentage); |
break; |
case base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE: |
// No need to change anything when there is no pressure. |
return; |
} |
+} |
+ |
+void RendererFrameManager::OnMemoryStateChange(base::MemoryState state) { |
+ switch (state) { |
+ case base::MemoryState::NORMAL: |
+ // It is not necessary to purge here. |
+ break; |
+ case base::MemoryState::THROTTLED: |
+ PurgeMemory(kCriticalPressurePercentage); |
+ break; |
+ case base::MemoryState::SUSPENDED: |
+ // Note that SUSPENDED never occurs in the main browser process so far. |
+ // Fall through. |
+ case base::MemoryState::UNKNOWN: |
+ NOTREACHED(); |
+ break; |
+ } |
+} |
+ |
+void RendererFrameManager::PurgeMemory(int percentage) { |
+ int saved_frame_limit = max_number_of_saved_frames_; |
+ if (saved_frame_limit <= 1) |
+ return; |
CullUnlockedFrames(std::max(1, (saved_frame_limit * percentage) / 100)); |
} |