Commit 58d1dd55 authored by Sebastien Marchand's avatar Sebastien Marchand Committed by Commit Bot

[PM] Use the SystemNode observer to notify of new process metrics data

Bug: 998546
Change-Id: Ibad528d47add2430955af8142aa1372fee5d0648
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1774792Reviewed-by: default avatarSigurður Ásgeirsson <siggi@chromium.org>
Commit-Queue: Sébastien Marchand <sebmarchand@chromium.org>
Cr-Commit-Position: refs/heads/master@{#692048}
parent 5c265045
...@@ -7,45 +7,15 @@ ...@@ -7,45 +7,15 @@
#include "chrome/browser/performance_manager/graph/graph_impl.h" #include "chrome/browser/performance_manager/graph/graph_impl.h"
#include "chrome/browser/performance_manager/graph/node_attached_data_impl.h" #include "chrome/browser/performance_manager/graph/node_attached_data_impl.h"
#include "chrome/browser/performance_manager/graph/process_node_impl.h" #include "chrome/browser/performance_manager/graph/process_node_impl.h"
#include "chrome/browser/performance_manager/graph/system_node_impl.h"
#include "services/resource_coordinator/public/cpp/memory_instrumentation/global_memory_dump.h" #include "services/resource_coordinator/public/cpp/memory_instrumentation/global_memory_dump.h"
namespace performance_manager { namespace performance_manager {
// Provides ProcessMetricsDecorator machinery access to some internals of a
// ProcessNodeImpl.
class ProcessMetricsDecoratorAccess {
public:
static std::unique_ptr<NodeAttachedData>* GetUniquePtrStorage(
ProcessNodeImpl* process_node) {
return &process_node->process_metrics_data_;
}
};
namespace { namespace {
// The process metrics refresh interval. // The process metrics refresh interval.
constexpr base::TimeDelta kRefreshTimerPeriod = base::TimeDelta::FromMinutes(2); constexpr base::TimeDelta kRefreshTimerPeriod = base::TimeDelta::FromMinutes(2);
// Private implementation of the node attached data. This keeps the complexity
// out of the header file.
class ProcessMetricsDataImpl
: public ProcessMetricsDecorator::Data,
public NodeAttachedDataImpl<ProcessMetricsDataImpl> {
public:
struct Traits : public NodeAttachedDataOwnedByNodeType<ProcessNodeImpl> {};
explicit ProcessMetricsDataImpl(const ProcessNodeImpl* process_node) {}
~ProcessMetricsDataImpl() override = default;
static std::unique_ptr<NodeAttachedData>* GetUniquePtrStorage(
ProcessNodeImpl* process_node) {
return ProcessMetricsDecoratorAccess::GetUniquePtrStorage(process_node);
}
private:
DISALLOW_COPY_AND_ASSIGN(ProcessMetricsDataImpl);
};
} // namespace } // namespace
ProcessMetricsDecorator::ProcessMetricsDecorator() = default; ProcessMetricsDecorator::ProcessMetricsDecorator() = default;
...@@ -93,25 +63,27 @@ void ProcessMetricsDecorator::DidGetMemoryUsage( ...@@ -93,25 +63,27 @@ void ProcessMetricsDecorator::DidGetMemoryUsage(
return; return;
auto* graph_impl = GraphImpl::FromGraph(graph_); auto* graph_impl = GraphImpl::FromGraph(graph_);
// Refresh the process nodes with the data contained in |process_dumps|.
// Processes for which we don't receive any data will retain the previously
// set value.
// TODO(sebmarchand): Check if we should set the data to 0 instead, or add a
// timestamp to the data.
for (const auto& process_dump_iter : process_dumps->process_dumps()) { for (const auto& process_dump_iter : process_dumps->process_dumps()) {
// Check if there's a process node associated with this PID. // Check if there's a process node associated with this PID.
auto* node = graph_impl->GetProcessNodeByPid(process_dump_iter.pid()); auto* node = graph_impl->GetProcessNodeByPid(process_dump_iter.pid());
if (!node) if (!node)
continue; continue;
auto* data = ProcessMetricsDataImpl::GetOrCreate(node); node->set_private_footprint_kb(
data->private_footprint_kb_ = process_dump_iter.os_dump().private_footprint_kb);
process_dump_iter.os_dump().private_footprint_kb; node->set_resident_set_kb(process_dump_iter.os_dump().resident_set_kb);
data->resident_set_kb_ = process_dump_iter.os_dump().resident_set_kb;
} }
GraphImpl::FromGraph(graph_)
->FindOrCreateSystemNodeImpl()
->OnProcessMemoryMetricsAvailable();
refresh_timer_.Reset(); refresh_timer_.Reset();
} }
// static
ProcessMetricsDecorator::Data* ProcessMetricsDecorator::Data::GetForTesting(
ProcessNode* process_node) {
return ProcessMetricsDataImpl::Get(ProcessNodeImpl::FromNode(process_node));
}
} // namespace performance_manager } // namespace performance_manager
...@@ -60,6 +60,17 @@ void LenientTestProcessMetricsDecorator::RequestProcessesMemoryMetrics( ...@@ -60,6 +60,17 @@ void LenientTestProcessMetricsDecorator::RequestProcessesMemoryMetrics(
memory_instrumentation::mojom::GlobalMemoryDump::New())); memory_instrumentation::mojom::GlobalMemoryDump::New()));
} }
class LenientMockSystemNodeObserver
: public SystemNodeImpl::ObserverDefaultImpl {
public:
LenientMockSystemNodeObserver() {}
~LenientMockSystemNodeObserver() override {}
MOCK_METHOD1(OnProcessMemoryMetricsAvailable, void(const SystemNode*));
};
using MockSystemNodeObserver =
::testing::StrictMock<LenientMockSystemNodeObserver>;
struct MemoryDumpProcInfo { struct MemoryDumpProcInfo {
base::ProcessId pid; base::ProcessId pid;
uint32_t resident_set_kb; uint32_t resident_set_kb;
...@@ -125,6 +136,9 @@ class ProcessMetricsDecoratorTest : public GraphTestHarness { ...@@ -125,6 +136,9 @@ class ProcessMetricsDecoratorTest : public GraphTestHarness {
}; };
TEST_F(ProcessMetricsDecoratorTest, RefreshTimer) { TEST_F(ProcessMetricsDecoratorTest, RefreshTimer) {
MockSystemNodeObserver sys_node_observer;
graph()->AddSystemNodeObserver(&sys_node_observer);
auto memory_dump = base::make_optional(std::move( auto memory_dump = base::make_optional(std::move(
GenerateMemoryDump({{mock_graph()->process->process_id(), GenerateMemoryDump({{mock_graph()->process->process_id(),
kFakeResidentSetKb, kFakePrivateFootprintKb}, kFakeResidentSetKb, kFakePrivateFootprintKb},
...@@ -135,27 +149,23 @@ TEST_F(ProcessMetricsDecoratorTest, RefreshTimer) { ...@@ -135,27 +149,23 @@ TEST_F(ProcessMetricsDecoratorTest, RefreshTimer) {
.WillOnce(testing::Return(testing::ByMove(std::move(memory_dump)))); .WillOnce(testing::Return(testing::ByMove(std::move(memory_dump))));
// There's no data available initially. // There's no data available initially.
auto* data = EXPECT_EQ(0U, mock_graph()->process->resident_set_kb());
ProcessMetricsDecorator::Data::GetForTesting(mock_graph()->process.get()); EXPECT_EQ(0U, mock_graph()->process->private_footprint_kb());
EXPECT_FALSE(data);
data = ProcessMetricsDecorator::Data::GetForTesting( EXPECT_CALL(sys_node_observer, OnProcessMemoryMetricsAvailable(testing::_));
mock_graph()->other_process.get());
EXPECT_FALSE(data);
// Advance the timer, this should trigger a refresh of the metrics. // Advance the timer, this should trigger a refresh of the metrics.
task_env().FastForwardBy(base::TimeDelta::FromMinutes(2)); task_env().FastForwardBy(base::TimeDelta::FromMinutes(2));
data = EXPECT_EQ(kFakeResidentSetKb, mock_graph()->process->resident_set_kb());
ProcessMetricsDecorator::Data::GetForTesting(mock_graph()->process.get()); EXPECT_EQ(kFakePrivateFootprintKb,
EXPECT_TRUE(data); mock_graph()->process->private_footprint_kb());
EXPECT_EQ(kFakeResidentSetKb, data->resident_set_kb_);
EXPECT_EQ(kFakePrivateFootprintKb, data->private_footprint_kb_); EXPECT_EQ(kFakeResidentSetKb, mock_graph()->other_process->resident_set_kb());
EXPECT_EQ(kFakePrivateFootprintKb,
data = ProcessMetricsDecorator::Data::GetForTesting( mock_graph()->other_process->private_footprint_kb());
mock_graph()->other_process.get());
EXPECT_TRUE(data); graph()->RemoveSystemNodeObserver(&sys_node_observer);
EXPECT_EQ(kFakeResidentSetKb, data->resident_set_kb_);
EXPECT_EQ(kFakePrivateFootprintKb, data->private_footprint_kb_);
} }
TEST_F(ProcessMetricsDecoratorTest, PartialRefresh) { TEST_F(ProcessMetricsDecoratorTest, PartialRefresh) {
...@@ -170,15 +180,9 @@ TEST_F(ProcessMetricsDecoratorTest, PartialRefresh) { ...@@ -170,15 +180,9 @@ TEST_F(ProcessMetricsDecoratorTest, PartialRefresh) {
task_env().FastForwardBy(base::TimeDelta::FromMinutes(2)); task_env().FastForwardBy(base::TimeDelta::FromMinutes(2));
auto* data = EXPECT_EQ(kFakeResidentSetKb, mock_graph()->process->resident_set_kb());
ProcessMetricsDecorator::Data::GetForTesting(mock_graph()->process.get()); EXPECT_EQ(kFakePrivateFootprintKb,
EXPECT_TRUE(data); mock_graph()->process->private_footprint_kb());
EXPECT_EQ(kFakeResidentSetKb, data->resident_set_kb_);
EXPECT_EQ(kFakePrivateFootprintKb, data->private_footprint_kb_);
data = ProcessMetricsDecorator::Data::GetForTesting(
mock_graph()->other_process.get());
EXPECT_FALSE(data);
// Do another partial refresh but this time for the other process. The data // Do another partial refresh but this time for the other process. The data
// attached to |mock_graph()->process| shouldn't change. // attached to |mock_graph()->process| shouldn't change.
...@@ -191,17 +195,14 @@ TEST_F(ProcessMetricsDecoratorTest, PartialRefresh) { ...@@ -191,17 +195,14 @@ TEST_F(ProcessMetricsDecoratorTest, PartialRefresh) {
task_env().FastForwardBy(base::TimeDelta::FromMinutes(2)); task_env().FastForwardBy(base::TimeDelta::FromMinutes(2));
data = EXPECT_EQ(kFakeResidentSetKb, mock_graph()->process->resident_set_kb());
ProcessMetricsDecorator::Data::GetForTesting(mock_graph()->process.get()); EXPECT_EQ(kFakePrivateFootprintKb,
EXPECT_TRUE(data); mock_graph()->process->private_footprint_kb());
EXPECT_EQ(kFakeResidentSetKb, data->resident_set_kb_);
EXPECT_EQ(kFakePrivateFootprintKb, data->private_footprint_kb_); EXPECT_EQ(kFakeResidentSetKb * 2,
mock_graph()->other_process->resident_set_kb());
data = ProcessMetricsDecorator::Data::GetForTesting( EXPECT_EQ(kFakePrivateFootprintKb * 2,
mock_graph()->other_process.get()); mock_graph()->other_process->private_footprint_kb());
EXPECT_TRUE(data);
EXPECT_EQ(kFakeResidentSetKb * 2, data->resident_set_kb_);
EXPECT_EQ(kFakePrivateFootprintKb * 2, data->private_footprint_kb_);
} }
TEST_F(ProcessMetricsDecoratorTest, RefreshFailure) { TEST_F(ProcessMetricsDecoratorTest, RefreshFailure) {
...@@ -210,9 +211,8 @@ TEST_F(ProcessMetricsDecoratorTest, RefreshFailure) { ...@@ -210,9 +211,8 @@ TEST_F(ProcessMetricsDecoratorTest, RefreshFailure) {
task_env().FastForwardBy(base::TimeDelta::FromMinutes(2)); task_env().FastForwardBy(base::TimeDelta::FromMinutes(2));
auto* data = EXPECT_EQ(0U, mock_graph()->process->resident_set_kb());
ProcessMetricsDecorator::Data::GetForTesting(mock_graph()->process.get()); EXPECT_EQ(0U, mock_graph()->process->private_footprint_kb());
EXPECT_FALSE(data);
} }
} // namespace performance_manager } // namespace performance_manager
...@@ -126,6 +126,7 @@ void ProcessNodeImpl::SetProcessImpl(base::Process process, ...@@ -126,6 +126,7 @@ void ProcessNodeImpl::SetProcessImpl(base::Process process,
// Also clear the measurement data (if any), as it references the previous // Also clear the measurement data (if any), as it references the previous
// process. // process.
private_footprint_kb_ = 0; private_footprint_kb_ = 0;
resident_set_kb_ = 0;
cumulative_cpu_usage_ = base::TimeDelta(); cumulative_cpu_usage_ = base::TimeDelta();
process_id_ = new_pid; process_id_ = new_pid;
...@@ -200,6 +201,11 @@ uint64_t ProcessNodeImpl::GetPrivateFootprintKb() const { ...@@ -200,6 +201,11 @@ uint64_t ProcessNodeImpl::GetPrivateFootprintKb() const {
return private_footprint_kb(); return private_footprint_kb();
} }
uint64_t ProcessNodeImpl::GetResidentSetKb() const {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
return resident_set_kb();
}
const RenderProcessHostProxy& ProcessNodeImpl::GetRenderProcessHostProxy() const RenderProcessHostProxy& ProcessNodeImpl::GetRenderProcessHostProxy()
const { const {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
......
...@@ -31,7 +31,7 @@ class WorkerNodeImpl; ...@@ -31,7 +31,7 @@ class WorkerNodeImpl;
// 1. Created, no PID. // 1. Created, no PID.
// 2. Process started, have PID - in the case where the associated render // 2. Process started, have PID - in the case where the associated render
// process fails to start, this state may not occur. // process fails to start, this state may not occur.
// 3. Process died or falied to start, have exit status. // 3. Process died or failed to start, have exit status.
// 4. Back to 2. // 4. Back to 2.
class ProcessNodeImpl class ProcessNodeImpl
: public PublicNodeImpl<ProcessNodeImpl, ProcessNode>, : public PublicNodeImpl<ProcessNodeImpl, ProcessNode>,
...@@ -68,6 +68,10 @@ class ProcessNodeImpl ...@@ -68,6 +68,10 @@ class ProcessNodeImpl
void set_cumulative_cpu_usage(base::TimeDelta cumulative_cpu_usage) { void set_cumulative_cpu_usage(base::TimeDelta cumulative_cpu_usage) {
cumulative_cpu_usage_ = cumulative_cpu_usage; cumulative_cpu_usage_ = cumulative_cpu_usage;
} }
uint64_t resident_set_kb() const { return resident_set_kb_; }
void set_resident_set_kb(uint64_t resident_set_kb) {
resident_set_kb_ = resident_set_kb;
}
base::TimeDelta cumulative_cpu_usage() const { return cumulative_cpu_usage_; } base::TimeDelta cumulative_cpu_usage() const { return cumulative_cpu_usage_; }
const base::flat_set<FrameNodeImpl*>& frame_nodes() const; const base::flat_set<FrameNodeImpl*>& frame_nodes() const;
...@@ -134,6 +138,7 @@ class ProcessNodeImpl ...@@ -134,6 +138,7 @@ class ProcessNodeImpl
double GetCpuUsage() const override; double GetCpuUsage() const override;
base::TimeDelta GetCumulativeCpuUsage() const override; base::TimeDelta GetCumulativeCpuUsage() const override;
uint64_t GetPrivateFootprintKb() const override; uint64_t GetPrivateFootprintKb() const override;
uint64_t GetResidentSetKb() const override;
const RenderProcessHostProxy& GetRenderProcessHostProxy() const override; const RenderProcessHostProxy& GetRenderProcessHostProxy() const override;
void OnAllFramesInProcessFrozen(); void OnAllFramesInProcessFrozen();
...@@ -144,6 +149,7 @@ class ProcessNodeImpl ...@@ -144,6 +149,7 @@ class ProcessNodeImpl
base::TimeDelta cumulative_cpu_usage_; base::TimeDelta cumulative_cpu_usage_;
uint64_t private_footprint_kb_ = 0u; uint64_t private_footprint_kb_ = 0u;
uint64_t resident_set_kb_ = 0;
base::ProcessId process_id_ = base::kNullProcessId; base::ProcessId process_id_ = base::kNullProcessId;
ObservedProperty::NotifiesAlways< ObservedProperty::NotifiesAlways<
...@@ -173,8 +179,6 @@ class ProcessNodeImpl ...@@ -173,8 +179,6 @@ class ProcessNodeImpl
// Inline storage for FrozenFrameAggregator user data. // Inline storage for FrozenFrameAggregator user data.
InternalNodeAttachedDataStorage<sizeof(uintptr_t) + 8> frozen_frame_data_; InternalNodeAttachedDataStorage<sizeof(uintptr_t) + 8> frozen_frame_data_;
std::unique_ptr<NodeAttachedData> process_metrics_data_;
DISALLOW_COPY_AND_ASSIGN(ProcessNodeImpl); DISALLOW_COPY_AND_ASSIGN(ProcessNodeImpl);
}; };
......
...@@ -67,10 +67,12 @@ TEST_F(ProcessNodeImplTest, ProcessLifeCycle) { ...@@ -67,10 +67,12 @@ TEST_F(ProcessNodeImplTest, ProcessLifeCycle) {
EXPECT_FALSE(process_node->exit_status()); EXPECT_FALSE(process_node->exit_status());
EXPECT_EQ(0U, process_node->private_footprint_kb()); EXPECT_EQ(0U, process_node->private_footprint_kb());
EXPECT_EQ(0U, process_node->resident_set_kb());
EXPECT_EQ(base::TimeDelta(), process_node->cumulative_cpu_usage()); EXPECT_EQ(base::TimeDelta(), process_node->cumulative_cpu_usage());
constexpr base::TimeDelta kCpuUsage = base::TimeDelta::FromMicroseconds(1); constexpr base::TimeDelta kCpuUsage = base::TimeDelta::FromMicroseconds(1);
process_node->set_private_footprint_kb(10u); process_node->set_private_footprint_kb(10u);
process_node->set_resident_set_kb(20u);
process_node->set_cumulative_cpu_usage(kCpuUsage); process_node->set_cumulative_cpu_usage(kCpuUsage);
// Kill it again. // Kill it again.
...@@ -81,6 +83,7 @@ TEST_F(ProcessNodeImplTest, ProcessLifeCycle) { ...@@ -81,6 +83,7 @@ TEST_F(ProcessNodeImplTest, ProcessLifeCycle) {
EXPECT_EQ(launch_time, process_node->launch_time()); EXPECT_EQ(launch_time, process_node->launch_time());
EXPECT_EQ(10u, process_node->private_footprint_kb()); EXPECT_EQ(10u, process_node->private_footprint_kb());
EXPECT_EQ(20u, process_node->resident_set_kb());
EXPECT_EQ(kCpuUsage, process_node->cumulative_cpu_usage()); EXPECT_EQ(kCpuUsage, process_node->cumulative_cpu_usage());
// Resurrect again and verify the launch time and measurements // Resurrect again and verify the launch time and measurements
...@@ -90,6 +93,7 @@ TEST_F(ProcessNodeImplTest, ProcessLifeCycle) { ...@@ -90,6 +93,7 @@ TEST_F(ProcessNodeImplTest, ProcessLifeCycle) {
EXPECT_EQ(launch2_time, process_node->launch_time()); EXPECT_EQ(launch2_time, process_node->launch_time());
EXPECT_EQ(0U, process_node->private_footprint_kb()); EXPECT_EQ(0U, process_node->private_footprint_kb());
EXPECT_EQ(0U, process_node->resident_set_kb());
EXPECT_EQ(base::TimeDelta(), process_node->cumulative_cpu_usage()); EXPECT_EQ(base::TimeDelta(), process_node->cumulative_cpu_usage());
} }
...@@ -254,6 +258,10 @@ TEST_F(ProcessNodeImplTest, PublicInterface) { ...@@ -254,6 +258,10 @@ TEST_F(ProcessNodeImplTest, PublicInterface) {
process_node->set_private_footprint_kb(628); process_node->set_private_footprint_kb(628);
EXPECT_EQ(process_node->private_footprint_kb(), EXPECT_EQ(process_node->private_footprint_kb(),
public_process_node->GetPrivateFootprintKb()); public_process_node->GetPrivateFootprintKb());
process_node->set_resident_set_kb(398);
EXPECT_EQ(process_node->resident_set_kb(),
public_process_node->GetResidentSetKb());
} }
} // namespace performance_manager } // namespace performance_manager
...@@ -24,4 +24,10 @@ SystemNodeImpl::~SystemNodeImpl() { ...@@ -24,4 +24,10 @@ SystemNodeImpl::~SystemNodeImpl() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
} }
void SystemNodeImpl::OnProcessMemoryMetricsAvailable() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
for (auto* observer : GetObservers())
observer->OnProcessMemoryMetricsAvailable(this);
}
} // namespace performance_manager } // namespace performance_manager
...@@ -27,6 +27,10 @@ class SystemNodeImpl : public PublicNodeImpl<SystemNodeImpl, SystemNode>, ...@@ -27,6 +27,10 @@ class SystemNodeImpl : public PublicNodeImpl<SystemNodeImpl, SystemNode>,
explicit SystemNodeImpl(GraphImpl* graph); explicit SystemNodeImpl(GraphImpl* graph);
~SystemNodeImpl() override; ~SystemNodeImpl() override;
// This should be called after refreshing the memory usage data of the process
// nodes.
void OnProcessMemoryMetricsAvailable();
private: private:
DISALLOW_COPY_AND_ASSIGN(SystemNodeImpl); DISALLOW_COPY_AND_ASSIGN(SystemNodeImpl);
}; };
......
...@@ -78,6 +78,7 @@ class LenientMockObserver : public SystemNodeImpl::Observer { ...@@ -78,6 +78,7 @@ class LenientMockObserver : public SystemNodeImpl::Observer {
MOCK_METHOD1(OnSystemNodeAdded, void(const SystemNode*)); MOCK_METHOD1(OnSystemNodeAdded, void(const SystemNode*));
MOCK_METHOD1(OnBeforeSystemNodeRemoved, void(const SystemNode*)); MOCK_METHOD1(OnBeforeSystemNodeRemoved, void(const SystemNode*));
MOCK_METHOD1(OnProcessMemoryMetricsAvailable, void(const SystemNode*));
void SetNotifiedSystemNode(const SystemNode* system_node) { void SetNotifiedSystemNode(const SystemNode* system_node) {
notified_system_node_ = system_node; notified_system_node_ = system_node;
...@@ -110,7 +111,10 @@ TEST_F(SystemNodeImplTest, ObserverWorks) { ...@@ -110,7 +111,10 @@ TEST_F(SystemNodeImplTest, ObserverWorks) {
const SystemNode* system_node = graph()->FindOrCreateSystemNode(); const SystemNode* system_node = graph()->FindOrCreateSystemNode();
EXPECT_EQ(system_node, obs.TakeNotifiedSystemNode()); EXPECT_EQ(system_node, obs.TakeNotifiedSystemNode());
// "OnProcessCPUUsageReady" is tested explicitly in the above unittests. EXPECT_CALL(obs, OnProcessMemoryMetricsAvailable(_))
.WillOnce(Invoke(&obs, &MockObserver::SetNotifiedSystemNode));
SystemNodeImpl::FromNode(system_node)->OnProcessMemoryMetricsAvailable();
EXPECT_EQ(system_node, obs.TakeNotifiedSystemNode());
// Release the system node and expect a call to "OnBeforeSystemNodeRemoved". // Release the system node and expect a call to "OnBeforeSystemNodeRemoved".
EXPECT_CALL(obs, OnBeforeSystemNodeRemoved(_)) EXPECT_CALL(obs, OnBeforeSystemNodeRemoved(_))
......
...@@ -89,10 +89,15 @@ class ProcessNode : public Node { ...@@ -89,10 +89,15 @@ class ProcessNode : public Node {
// lifetime, expressed as CPU seconds. // lifetime, expressed as CPU seconds.
virtual base::TimeDelta GetCumulativeCpuUsage() const = 0; virtual base::TimeDelta GetCumulativeCpuUsage() const = 0;
// Returns the most recently measured private memory footprint of the render // Returns the most recently measured private memory footprint of the process.
// process, in kilobytes. // This is roughly private, anonymous, non-discardable, resident or swapped
// memory in kilobytes. For more details, see https://goo.gl/3kPb9S.
virtual uint64_t GetPrivateFootprintKb() const = 0; virtual uint64_t GetPrivateFootprintKb() const = 0;
// Returns the most recently measured resident set of the process, in
// kilobytes.
virtual uint64_t GetResidentSetKb() const = 0;
// Returns a proxy to the RenderProcessHost associated with this node. The // Returns a proxy to the RenderProcessHost associated with this node. The
// proxy may only be dereferenced on the UI thread. // proxy may only be dereferenced on the UI thread.
virtual const RenderProcessHostProxy& GetRenderProcessHostProxy() const = 0; virtual const RenderProcessHostProxy& GetRenderProcessHostProxy() const = 0;
......
...@@ -41,6 +41,10 @@ class SystemNodeObserver { ...@@ -41,6 +41,10 @@ class SystemNodeObserver {
// Called before the |system_node| is removed from the graph. // Called before the |system_node| is removed from the graph.
virtual void OnBeforeSystemNodeRemoved(const SystemNode* system_node) = 0; virtual void OnBeforeSystemNodeRemoved(const SystemNode* system_node) = 0;
// Called when a new set of process memory metrics is available.
virtual void OnProcessMemoryMetricsAvailable(
const SystemNode* system_node) = 0;
private: private:
DISALLOW_COPY_AND_ASSIGN(SystemNodeObserver); DISALLOW_COPY_AND_ASSIGN(SystemNodeObserver);
}; };
...@@ -56,6 +60,8 @@ class SystemNode::ObserverDefaultImpl : public SystemNodeObserver { ...@@ -56,6 +60,8 @@ class SystemNode::ObserverDefaultImpl : public SystemNodeObserver {
// SystemNodeObserver implementation: // SystemNodeObserver implementation:
void OnSystemNodeAdded(const SystemNode* system_node) override {} void OnSystemNodeAdded(const SystemNode* system_node) override {}
void OnBeforeSystemNodeRemoved(const SystemNode* system_node) override {} void OnBeforeSystemNodeRemoved(const SystemNode* system_node) override {}
void OnProcessMemoryMetricsAvailable(const SystemNode* system_node) override {
}
private: private:
DISALLOW_COPY_AND_ASSIGN(ObserverDefaultImpl); DISALLOW_COPY_AND_ASSIGN(ObserverDefaultImpl);
......
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