Commit a7ddad19 authored by Patrick Monette's avatar Patrick Monette Committed by Chromium LUCI CQ

Don't leak ProcessMonitor

The single instance is now owned by
ChromeBrowserMainExtraPartsPerformanceMonitor but it can still be
retrieved by the Get() method.

Bug: 1166820
Change-Id: I27300c2fafb9d5ce04d73397dd791c85efd9393b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2630368
Commit-Queue: Patrick Monette <pmonette@chromium.org>
Reviewed-by: default avatarTommy Nyquist <nyquist@chromium.org>
Reviewed-by: default avatarSébastien Marchand <sebmarchand@chromium.org>
Cr-Commit-Position: refs/heads/master@{#844590}
parent 0597db0a
...@@ -1727,7 +1727,11 @@ bool ChromeBrowserMainParts::MainMessageLoopRun(int* result_code) { ...@@ -1727,7 +1727,11 @@ bool ChromeBrowserMainParts::MainMessageLoopRun(int* result_code) {
DCHECK(base::CurrentUIThread::IsSet()); DCHECK(base::CurrentUIThread::IsSet());
performance_monitor::ProcessMonitor::GetInstance()->StartGatherCycle(); // The ProcessMonitor is responsible for gathering important processes
// metrics.
// TODO(1167290): Can this be moved to PreMainMessageLoopStart() without
// impacting those metrics?
performance_monitor::ProcessMonitor::Get()->StartGatherCycle();
g_run_loop->Run(); g_run_loop->Run();
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#include "chrome/browser/performance_monitor/chrome_browser_main_extra_parts_performance_monitor.h" #include "chrome/browser/performance_monitor/chrome_browser_main_extra_parts_performance_monitor.h"
#include "chrome/browser/performance_monitor/process_monitor.h"
#include "chrome/browser/performance_monitor/system_monitor.h" #include "chrome/browser/performance_monitor/system_monitor.h"
ChromeBrowserMainExtraPartsPerformanceMonitor:: ChromeBrowserMainExtraPartsPerformanceMonitor::
...@@ -12,6 +13,10 @@ ChromeBrowserMainExtraPartsPerformanceMonitor:: ...@@ -12,6 +13,10 @@ ChromeBrowserMainExtraPartsPerformanceMonitor::
ChromeBrowserMainExtraPartsPerformanceMonitor:: ChromeBrowserMainExtraPartsPerformanceMonitor::
~ChromeBrowserMainExtraPartsPerformanceMonitor() = default; ~ChromeBrowserMainExtraPartsPerformanceMonitor() = default;
void ChromeBrowserMainExtraPartsPerformanceMonitor::PreMainMessageLoopStart() {
process_monitor_ = performance_monitor::ProcessMonitor::Create();
}
void ChromeBrowserMainExtraPartsPerformanceMonitor::PostMainMessageLoopStart() { void ChromeBrowserMainExtraPartsPerformanceMonitor::PostMainMessageLoopStart() {
system_monitor_ = performance_monitor::SystemMonitor::Create(); system_monitor_ = performance_monitor::SystemMonitor::Create();
} }
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include "chrome/browser/chrome_browser_main_extra_parts.h" #include "chrome/browser/chrome_browser_main_extra_parts.h"
namespace performance_monitor { namespace performance_monitor {
class ProcessMonitor;
class SystemMonitor; class SystemMonitor;
} // namespace performance_monitor } // namespace performance_monitor
...@@ -25,9 +26,12 @@ class ChromeBrowserMainExtraPartsPerformanceMonitor ...@@ -25,9 +26,12 @@ class ChromeBrowserMainExtraPartsPerformanceMonitor
const ChromeBrowserMainExtraPartsPerformanceMonitor&) = delete; const ChromeBrowserMainExtraPartsPerformanceMonitor&) = delete;
// ChromeBrowserMainExtraParts: // ChromeBrowserMainExtraParts:
void PreMainMessageLoopStart() override;
void PostMainMessageLoopStart() override; void PostMainMessageLoopStart() override;
private: private:
std::unique_ptr<performance_monitor::ProcessMonitor> process_monitor_;
// The system monitor instance, used by some subsystems to collect the system // The system monitor instance, used by some subsystems to collect the system
// metrics they need. // metrics they need.
std::unique_ptr<performance_monitor::SystemMonitor> system_monitor_; std::unique_ptr<performance_monitor::SystemMonitor> system_monitor_;
......
...@@ -37,8 +37,8 @@ namespace { ...@@ -37,8 +37,8 @@ namespace {
// collections. // collections.
constexpr base::TimeDelta kGatherInterval = base::TimeDelta::FromSeconds(120); constexpr base::TimeDelta kGatherInterval = base::TimeDelta::FromSeconds(120);
base::LazyInstance<ProcessMonitor>::DestructorAtExit g_monitor = // The global instance.
LAZY_INSTANCE_INITIALIZER; ProcessMonitor* g_process_monitor = nullptr;
void GatherMetricsForRenderProcess(content::RenderProcessHost* host, void GatherMetricsForRenderProcess(content::RenderProcessHost* host,
ProcessMetricsMetadata* data) { ProcessMetricsMetadata* data) {
...@@ -74,13 +74,20 @@ void GatherMetricsForRenderProcess(content::RenderProcessHost* host, ...@@ -74,13 +74,20 @@ void GatherMetricsForRenderProcess(content::RenderProcessHost* host,
} // namespace } // namespace
ProcessMonitor::ProcessMonitor() = default; // static
std::unique_ptr<ProcessMonitor> ProcessMonitor::Create() {
ProcessMonitor::~ProcessMonitor() = default; DCHECK(!g_process_monitor);
return base::WrapUnique(new ProcessMonitor());
}
// static // static
ProcessMonitor* ProcessMonitor::GetInstance() { ProcessMonitor* ProcessMonitor::Get() {
return g_monitor.Pointer(); return g_process_monitor;
}
ProcessMonitor::~ProcessMonitor() {
DCHECK(g_process_monitor);
g_process_monitor = nullptr;
} }
void ProcessMonitor::StartGatherCycle() { void ProcessMonitor::StartGatherCycle() {
...@@ -89,6 +96,32 @@ void ProcessMonitor::StartGatherCycle() { ...@@ -89,6 +96,32 @@ void ProcessMonitor::StartGatherCycle() {
&ProcessMonitor::GatherMetricsMapOnUIThread); &ProcessMonitor::GatherMetricsMapOnUIThread);
} }
ProcessMonitor::ProcessMonitor() {
DCHECK(!g_process_monitor);
g_process_monitor = this;
}
void ProcessMonitor::MarkProcessAsAlive(
const ProcessMetricsMetadata& process_data,
int current_update_sequence) {
const base::ProcessHandle& handle = process_data.handle;
if (handle == base::kNullProcessHandle) {
// Process may not be valid yet.
return;
}
auto process_metrics_iter = metrics_map_.find(handle);
if (process_metrics_iter == metrics_map_.end()) {
// If we're not already watching the process, let's initialize it.
metrics_map_[handle] = std::make_unique<ProcessMetricsHistory>();
metrics_map_[handle]->Initialize(process_data, current_update_sequence);
} else {
// If we are watching the process, touch it to keep it alive.
ProcessMetricsHistory* process_metrics = process_metrics_iter->second.get();
process_metrics->set_last_update_sequence(current_update_sequence);
}
}
void ProcessMonitor::GatherMetricsMapOnUIThread() { void ProcessMonitor::GatherMetricsMapOnUIThread() {
DCHECK_CURRENTLY_ON(BrowserThread::UI); DCHECK_CURRENTLY_ON(BrowserThread::UI);
...@@ -116,27 +149,6 @@ void ProcessMonitor::GatherMetricsMapOnUIThread() { ...@@ -116,27 +149,6 @@ void ProcessMonitor::GatherMetricsMapOnUIThread() {
base::Unretained(this), current_update_sequence)); base::Unretained(this), current_update_sequence));
} }
void ProcessMonitor::MarkProcessAsAlive(
const ProcessMetricsMetadata& process_data,
int current_update_sequence) {
const base::ProcessHandle& handle = process_data.handle;
if (handle == base::kNullProcessHandle) {
// Process may not be valid yet.
return;
}
auto process_metrics_iter = metrics_map_.find(handle);
if (process_metrics_iter == metrics_map_.end()) {
// If we're not already watching the process, let's initialize it.
metrics_map_[handle] = std::make_unique<ProcessMetricsHistory>();
metrics_map_[handle]->Initialize(process_data, current_update_sequence);
} else {
// If we are watching the process, touch it to keep it alive.
ProcessMetricsHistory* process_metrics = process_metrics_iter->second.get();
process_metrics->set_last_update_sequence(current_update_sequence);
}
}
void ProcessMonitor::GatherMetricsMapOnIOThread(int current_update_sequence) { void ProcessMonitor::GatherMetricsMapOnIOThread(int current_update_sequence) {
DCHECK_CURRENTLY_ON(BrowserThread::IO); DCHECK_CURRENTLY_ON(BrowserThread::IO);
......
...@@ -21,13 +21,19 @@ class ProcessMetricsHistory; ...@@ -21,13 +21,19 @@ class ProcessMetricsHistory;
// ProcessMonitor is a tool which periodically monitors performance metrics // ProcessMonitor is a tool which periodically monitors performance metrics
// of all the Chrome processes for histogram logging and possibly taking action // of all the Chrome processes for histogram logging and possibly taking action
// upon noticing serious performance degradation. // upon noticing serious performance degradation.
//
// TODO(sebmarchand): Make this class not a singleton.
class ProcessMonitor { class ProcessMonitor {
public: public:
// Returns the current ProcessMonitor instance if one exists; otherwise // Creates and returns the application-wide ProcessMonitor. Can only be called
// constructs a new ProcessMonitor. // if no ProcessMonitor instances exists in the current process. The caller
static ProcessMonitor* GetInstance(); // owns the created instance. The current process' instance can be retrieved
// with Get().
static std::unique_ptr<ProcessMonitor> Create();
// Returns the application-wide ProcessMonitor if one exists; otherwise
// returns nullptr.
static ProcessMonitor* Get();
~ProcessMonitor();
// Start the cycle of metrics gathering. // Start the cycle of metrics gathering.
void StartGatherCycle(); void StartGatherCycle();
...@@ -39,7 +45,6 @@ class ProcessMonitor { ...@@ -39,7 +45,6 @@ class ProcessMonitor {
std::map<base::ProcessHandle, std::unique_ptr<ProcessMetricsHistory>>; std::map<base::ProcessHandle, std::unique_ptr<ProcessMetricsHistory>>;
ProcessMonitor(); ProcessMonitor();
~ProcessMonitor();
// Mark the given process as alive in the current update iteration. // Mark the given process as alive in the current update iteration.
// This means adding an entry to the map of watched processes if it's not // This means adding an entry to the map of watched processes if it's not
......
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