Commit 8c008810 authored by Sebastien Marchand's avatar Sebastien Marchand Committed by Commit Bot

Create ChromeBrowserMainExtraPartsMemory.

This CL creates a new ChromeBrowserMainExtraParts derived class to own
memory management related classes. This includes the new
EnterpriseMemoryLimitPrefObserver, which tracks changes to the
TotalResidentSetLimitMb enterprise policy and starts/stops the
EnterpriseMemoryLimitEvaluator (which the PrefObserver owns) accordingly.
Larger project documentation here:
https://docs.google.com/document/d/1W3FPDyjIAKBcFGNYsHA3EKR1FHrJlbBaqT4_RUnxzq0/edit?ts=5d3f5714#

This also disable the memory::MemoryPressureMonitor as it's not being
used (we're using base::util::MemoryPressureMonitor).

Bug: 980965
Change-Id: Iae632b6681d1574006d38fee9b38bf4d6e5545af
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1790290Reviewed-by: default avatarScott Violet <sky@chromium.org>
Commit-Queue: Sébastien Marchand <sebmarchand@chromium.org>
Cr-Commit-Position: refs/heads/master@{#705144}
parent abbe4b95
......@@ -765,6 +765,8 @@ jumbo_split_static_library("browser") {
"media/webrtc/window_icon_util_chromeos.cc",
"media/webrtc/window_icon_util_mac.mm",
"media/webrtc/window_icon_util_win.cc",
"memory/chrome_browser_main_extra_parts_memory.cc",
"memory/chrome_browser_main_extra_parts_memory.h",
"memory/enterprise_memory_limit_evaluator.cc",
"memory/enterprise_memory_limit_evaluator.h",
"memory/enterprise_memory_limit_pref_observer.cc",
......
......@@ -41,8 +41,6 @@
#include "build/branding_buildflags.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/first_run/first_run.h"
#include "chrome/browser/memory/memory_pressure_monitor.h"
#include "chrome/browser/memory/swap_thrashing_monitor.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/profiles/profile_shortcut_manager.h"
#include "chrome/browser/safe_browsing/chrome_cleaner/settings_resetter_win.h"
......@@ -610,17 +608,6 @@ void ChromeBrowserMainPartsWin::PostBrowserStart() {
base::PostDelayedTask(FROM_HERE, {content::BrowserThread::UI},
base::BindOnce(&DetectFaultTolerantHeap),
base::TimeDelta::FromMinutes(1));
// Start the swap thrashing monitor if it's enabled.
//
// TODO(sebmarchand): Delay the initialization of this monitor once we start
// using this feature by default, this is currently enabled at startup to make
// it easier to experiment with this monitor.
if (base::FeatureList::IsEnabled(features::kSwapThrashingMonitor))
memory::SwapThrashingMonitor::Initialize();
if (base::FeatureList::IsEnabled(features::kNewMemoryPressureMonitor))
memory_pressure_monitor_ = memory::MemoryPressureMonitor::Create();
}
// static
......
......@@ -19,10 +19,6 @@ namespace base {
class CommandLine;
}
namespace memory {
class MemoryPressureMonitor;
}
// Handle uninstallation when given the appropriate the command-line switch.
// If |chrome_still_running| is true a modal dialog will be shown asking the
// user to close the other chrome instance.
......@@ -78,11 +74,6 @@ class ChromeBrowserMainPartsWin : public ChromeBrowserMainParts {
// Watches module load events and forwards them to the ModuleDatabase.
std::unique_ptr<ModuleWatcher> module_watcher_;
// The memory pressure monitor. This is currently only being used to record
// metrics, the base::MemoryPressureMonitor is still being used to emit memory
// pressure signals.
std::unique_ptr<memory::MemoryPressureMonitor> memory_pressure_monitor_;
DISALLOW_COPY_AND_ASSIGN(ChromeBrowserMainPartsWin);
};
......
......@@ -72,6 +72,7 @@
#include "chrome/browser/media/webrtc/audio_debug_recordings_handler.h"
#include "chrome/browser/media/webrtc/media_capture_devices_dispatcher.h"
#include "chrome/browser/media/webrtc/webrtc_logging_controller.h"
#include "chrome/browser/memory/chrome_browser_main_extra_parts_memory.h"
#include "chrome/browser/metrics/chrome_browser_main_extra_parts_metrics.h"
#include "chrome/browser/metrics/chrome_feature_list_creator.h"
#include "chrome/browser/nacl_host/nacl_browser_delegate_impl.h"
......@@ -1251,6 +1252,8 @@ ChromeContentBrowserClient::CreateBrowserMainParts(
main_parts->AddParts(new ChromeBrowserMainExtraPartsProfiling);
main_parts->AddParts(new ChromeBrowserMainExtraPartsMemory);
chrome::AddMetricsExtraParts(main_parts.get());
return main_parts;
......
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/memory/chrome_browser_main_extra_parts_memory.h"
#include "base/memory/memory_pressure_monitor.h"
#include "build/build_config.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/memory/enterprise_memory_limit_pref_observer.h"
#if defined(OS_WIN)
#include "chrome/browser/memory/swap_thrashing_monitor.h"
#endif
ChromeBrowserMainExtraPartsMemory::ChromeBrowserMainExtraPartsMemory() = default;
ChromeBrowserMainExtraPartsMemory::~ChromeBrowserMainExtraPartsMemory() =
default;
void ChromeBrowserMainExtraPartsMemory::PostBrowserStart() {
#if defined(OS_WIN)
// Start the swap thrashing monitor if it's enabled.
//
// TODO(sebmarchand): Delay the initialization of this monitor once we start
// using this feature by default, this is currently enabled at startup to make
// it easier to experiment with this monitor.
if (base::FeatureList::IsEnabled(features::kSwapThrashingMonitor))
memory::SwapThrashingMonitor::Initialize();
#endif
// The MemoryPressureMonitor might not be available in some tests.
if (base::MemoryPressureMonitor::Get() &&
memory::EnterpriseMemoryLimitPrefObserver::PlatformIsSupported()) {
memory_limit_pref_observer_ =
std::make_unique<memory::EnterpriseMemoryLimitPrefObserver>(
g_browser_process->local_state());
}
}
void ChromeBrowserMainExtraPartsMemory::PostMainMessageLoopRun() {
// |memory_limit_pref_observer_| must be destroyed before its |pref_service_|
// is destroyed, as the observer's PrefChangeRegistrar's destructor uses the
// pref_service.
memory_limit_pref_observer_.reset();
}
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_MEMORY_CHROME_BROWSER_MAIN_EXTRA_PARTS_MEMORY_H_
#define CHROME_BROWSER_MEMORY_CHROME_BROWSER_MAIN_EXTRA_PARTS_MEMORY_H_
#include <memory>
#include "base/macros.h"
#include "chrome/browser/chrome_browser_main_extra_parts.h"
namespace memory {
class EnterpriseMemoryLimitPrefObserver;
} // namespace memory
// Wrapper that owns and initialize the browser memory-related extra parts.
class ChromeBrowserMainExtraPartsMemory : public ChromeBrowserMainExtraParts {
public:
ChromeBrowserMainExtraPartsMemory();
~ChromeBrowserMainExtraPartsMemory() override;
private:
// ChromeBrowserMainExtraParts overrides.
void PostBrowserStart() override;
void PostMainMessageLoopRun() override;
// Tracks changes to the MemoryLimitMbEnabled enterprise policy, and
// starts/stops the EnterpriseMemoryLimitEvaluator accordingly.
//
// Only supported on some platforms, see
// EnterpriseMemoryLimitPrefObserver::PlatformIsSupported for the list of
// supported platforms.
std::unique_ptr<memory::EnterpriseMemoryLimitPrefObserver>
memory_limit_pref_observer_;
DISALLOW_COPY_AND_ASSIGN(ChromeBrowserMainExtraPartsMemory);
};
#endif // CHROME_BROWSER_MEMORY_CHROME_BROWSER_MAIN_EXTRA_PARTS_MEMORY_H_
......@@ -7,8 +7,14 @@
#include "base/bind.h"
#include "base/memory/memory_pressure_monitor.h"
#include "base/util/memory_pressure/multi_source_memory_pressure_monitor.h"
#include "build/build_config.h"
#include "chrome/browser/resource_coordinator/utils.h"
#include "chrome/common/pref_names.h"
#if !defined(OS_ANDROID)
#include "chrome/browser/resource_coordinator/tab_lifecycle_unit_source.h"
#endif
namespace memory {
namespace {
......@@ -35,8 +41,20 @@ EnterpriseMemoryLimitPrefObserver::EnterpriseMemoryLimitPrefObserver(
EnterpriseMemoryLimitPrefObserver::~EnterpriseMemoryLimitPrefObserver() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (evaluator_->IsRunning())
if (evaluator_->IsRunning()) {
#if !defined(OS_ANDROID)
resource_coordinator::GetTabLifecycleUnitSource()
->SetMemoryLimitEnterprisePolicyFlag(false);
#endif
evaluator_->Stop();
}
}
bool EnterpriseMemoryLimitPrefObserver::PlatformIsSupported() {
#if defined(OS_WIN) || defined(OS_MACOSX)
return true;
#endif
return false;
}
// static
......@@ -59,6 +77,11 @@ void EnterpriseMemoryLimitPrefObserver::GetPref() {
} else if (evaluator_->IsRunning()) {
evaluator_->Stop();
}
#if !defined(OS_ANDROID)
resource_coordinator::GetTabLifecycleUnitSource()
->SetMemoryLimitEnterprisePolicyFlag(pref->IsManaged());
#endif
}
} // namespace memory
......@@ -20,6 +20,9 @@ class EnterpriseMemoryLimitPrefObserver {
explicit EnterpriseMemoryLimitPrefObserver(PrefService* pref_service);
~EnterpriseMemoryLimitPrefObserver();
// Returns true if the current platform is supported, false otherwise.
static bool PlatformIsSupported();
// Registers the TotalMemoryLimitMb pref with the provided PrefRegistry.
// Should only be called by RegisterLocalState() in
// chrome/browser/prefs/browser_prefs.cc.
......
......@@ -602,12 +602,16 @@ bool TabLifecycleUnitSource::TabLifecycleUnit::CanDiscard(
// NOTE: These do not currently provide DecisionDetails!
#if !defined(OS_CHROMEOS)
if (reason == LifecycleUnitDiscardReason::URGENT) {
// Limit urgent discarding to once only.
if (GetDiscardCount() > 0)
// Limit urgent discarding to once only, unless discarding for the
// enterprise memory limit feature.
if (GetDiscardCount() > 0 &&
!GetTabSource()->memory_limit_enterprise_policy())
return false;
// Protect non-visible tabs from urgent discarding for a period of time.
if (web_contents()->GetVisibility() != content::Visibility::VISIBLE) {
base::TimeDelta time_in_bg = NowTicks() - GetWallTimeWhenHidden();
// TODO(sebmarchand): Check if this should be lowered when the enterprise
// memory limit feature is set.
if (time_in_bg < kBackgroundUrgentProtectionTime)
return false;
}
......
......@@ -222,6 +222,10 @@ void TabLifecycleUnitSource::SetFocusedTabStripModelForTesting(
UpdateFocusedTab();
}
void TabLifecycleUnitSource::SetMemoryLimitEnterprisePolicyFlag(bool enabled) {
memory_limit_enterprise_policy_ = enabled;
}
void TabLifecycleUnitSource::OnFirstLifecycleUnitCreated() {
// In production builds monitor the policy override of the lifecycles feature.
// This class owns the monitor so it is okay to use base::Unretained. Note
......
......@@ -74,6 +74,13 @@ class TabLifecycleUnitSource : public BrowserListObserver,
return tab_lifecycles_enterprise_policy_;
}
// Returns the state of the MemoryLimitMbEnabled enterprise policy.
bool memory_limit_enterprise_policy() const {
return memory_limit_enterprise_policy_;
}
void SetMemoryLimitEnterprisePolicyFlag(bool enabled);
protected:
class TabLifecycleUnitHolder;
......@@ -187,6 +194,9 @@ class TabLifecycleUnitSource : public BrowserListObserver,
// The enterprise policy for overriding the tab lifecycles feature.
bool tab_lifecycles_enterprise_policy_ = true;
// The enterprise policy for setting a limit on total physical memory usage.
bool memory_limit_enterprise_policy_ = false;
// In official production builds this monitors policy settings and reflects
// them in |tab_lifecycles_enterprise_policy_|.
std::unique_ptr<TabLifecylesEnterprisePreferenceMonitor>
......
......@@ -373,6 +373,11 @@ TEST_F(TabLifecycleUnitTest, UrgentDiscardProtections) {
LifecycleUnitDiscardReason::PROACTIVE);
ExpectCanDiscardFalseTrivial(&tab_lifecycle_unit,
LifecycleUnitDiscardReason::URGENT);
// The tab should be discardable a second time when the memory limit
// enterprise policy is set.
GetTabLifecycleUnitSource()->SetMemoryLimitEnterprisePolicyFlag(true);
ExpectCanDiscardTrue(&tab_lifecycle_unit, LifecycleUnitDiscardReason::URGENT);
}
#endif // !defined(OS_CHROMEOS)
......
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