Commit 43e035ee authored by erikchen's avatar erikchen Committed by Commit Bot

Add RequestPrivateMemoryFootprint method to MemoryInstrumentation.

Most clients only need private memory footprint, but the existing methods would
still query all the MemoryDumpProviders and then filter the results. This CL
adds a new method that avoids querying MemoryDumpProviders.

Bug: 851712
Change-Id: I269be2b5a74c32205ba6f4087a9bb8affb9cffb6
Reviewed-on: https://chromium-review.googlesource.com/1098623Reviewed-by: default avatarPrimiano Tucci <primiano@chromium.org>
Reviewed-by: default avatarNico Weber <thakis@chromium.org>
Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Commit-Queue: Erik Chen <erikchen@chromium.org>
Cr-Commit-Position: refs/heads/master@{#567417}
parent 2e0857a0
...@@ -360,9 +360,10 @@ void MemoryDetails::CollectChildInfoOnUIThread() { ...@@ -360,9 +360,10 @@ void MemoryDetails::CollectChildInfoOnUIThread() {
// Using AdaptCallbackForRepeating allows for an easier transition to // Using AdaptCallbackForRepeating allows for an easier transition to
// OnceCallbacks for https://crbug.com/714018. // OnceCallbacks for https://crbug.com/714018.
memory_instrumentation::MemoryInstrumentation::GetInstance() memory_instrumentation::MemoryInstrumentation::GetInstance()
->RequestGlobalDump(std::vector<std::string>(), ->RequestPrivateMemoryFootprint(
base::AdaptCallbackForRepeating(base::BindOnce( base::kNullProcessId,
&MemoryDetails::DidReceiveMemoryDump, this))); base::AdaptCallbackForRepeating(
base::BindOnce(&MemoryDetails::DidReceiveMemoryDump, this)));
} }
void MemoryDetails::DidReceiveMemoryDump( void MemoryDetails::DidReceiveMemoryDump(
......
...@@ -586,7 +586,7 @@ void DataReductionProxyMetricsObserver::RequestProcessDump( ...@@ -586,7 +586,7 @@ void DataReductionProxyMetricsObserver::RequestProcessDump(
memory_instrumentation::MemoryInstrumentation::RequestGlobalDumpCallback memory_instrumentation::MemoryInstrumentation::RequestGlobalDumpCallback
callback) { callback) {
memory_instrumentation::MemoryInstrumentation::GetInstance() memory_instrumentation::MemoryInstrumentation::GetInstance()
->RequestGlobalDumpForPid(pid, callback); ->RequestPrivateMemoryFootprint(pid, callback);
} }
} // namespace data_reduction_proxy } // namespace data_reduction_proxy
...@@ -655,10 +655,10 @@ void PrerenderContents::DestroyWhenUsingTooManyResources() { ...@@ -655,10 +655,10 @@ void PrerenderContents::DestroyWhenUsingTooManyResources() {
// Using AdaptCallbackForRepeating allows for an easier transition to // Using AdaptCallbackForRepeating allows for an easier transition to
// OnceCallbacks for https://crbug.com/714018. // OnceCallbacks for https://crbug.com/714018.
memory_instrumentation::MemoryInstrumentation::GetInstance() memory_instrumentation::MemoryInstrumentation::GetInstance()
->RequestGlobalDumpForPid(process_pid_, ->RequestPrivateMemoryFootprint(
base::AdaptCallbackForRepeating(base::BindOnce( process_pid_, base::AdaptCallbackForRepeating(base::BindOnce(
&PrerenderContents::DidGetMemoryUsage, &PrerenderContents::DidGetMemoryUsage,
weak_factory_.GetWeakPtr()))); weak_factory_.GetWeakPtr())));
} }
void PrerenderContents::DidGetMemoryUsage( void PrerenderContents::DidGetMemoryUsage(
......
...@@ -122,7 +122,8 @@ void BackgroundProfilingTriggers::PerformMemoryUsageChecks() { ...@@ -122,7 +122,8 @@ void BackgroundProfilingTriggers::PerformMemoryUsageChecks() {
[](base::WeakPtr<BackgroundProfilingTriggers> weak_ptr, [](base::WeakPtr<BackgroundProfilingTriggers> weak_ptr,
std::vector<base::ProcessId> result) { std::vector<base::ProcessId> result) {
memory_instrumentation::MemoryInstrumentation::GetInstance() memory_instrumentation::MemoryInstrumentation::GetInstance()
->RequestGlobalDump( ->RequestPrivateMemoryFootprint(
base::kNullProcessId,
base::Bind(&BackgroundProfilingTriggers::OnReceivedMemoryDump, base::Bind(&BackgroundProfilingTriggers::OnReceivedMemoryDump,
std::move(weak_ptr), std::move(result))); std::move(weak_ptr), std::move(result)));
}, },
......
...@@ -140,9 +140,11 @@ void RenderProcessProbeImpl:: ...@@ -140,9 +140,11 @@ void RenderProcessProbeImpl::
// Dispatch the memory collection request. // Dispatch the memory collection request.
memory_instrumentation::MemoryInstrumentation::GetInstance() memory_instrumentation::MemoryInstrumentation::GetInstance()
->RequestGlobalDump(base::BindRepeating( ->RequestPrivateMemoryFootprint(
&RenderProcessProbeImpl::ProcessGlobalMemoryDumpAndDispatchOnIOThread, base::kNullProcessId,
base::Unretained(this), collection_start_time)); base::BindRepeating(&RenderProcessProbeImpl::
ProcessGlobalMemoryDumpAndDispatchOnIOThread,
base::Unretained(this), collection_start_time));
RenderProcessInfoMap::iterator iter = render_process_info_map_.begin(); RenderProcessInfoMap::iterator iter = render_process_info_map_.begin();
while (iter != render_process_info_map_.end()) { while (iter != render_process_info_map_.end()) {
......
...@@ -586,7 +586,8 @@ void TaskManagerImpl::Refresh() { ...@@ -586,7 +586,8 @@ void TaskManagerImpl::Refresh() {
auto callback = base::Bind(&TaskManagerImpl::OnReceivedMemoryDump, auto callback = base::Bind(&TaskManagerImpl::OnReceivedMemoryDump,
weak_ptr_factory_.GetWeakPtr()); weak_ptr_factory_.GetWeakPtr());
memory_instrumentation::MemoryInstrumentation::GetInstance() memory_instrumentation::MemoryInstrumentation::GetInstance()
->RequestGlobalDump(std::move(callback)); ->RequestPrivateMemoryFootprint(base::kNullProcessId,
std::move(callback));
} }
if (base::FeatureList::IsEnabled(network::features::kNetworkService) && if (base::FeatureList::IsEnabled(network::features::kNetworkService) &&
......
...@@ -53,15 +53,16 @@ std::unique_ptr<GlobalMemoryDump> DoGlobalDump() { ...@@ -53,15 +53,16 @@ std::unique_ptr<GlobalMemoryDump> DoGlobalDump() {
std::unique_ptr<GlobalMemoryDump> result = nullptr; std::unique_ptr<GlobalMemoryDump> result = nullptr;
base::RunLoop run_loop; base::RunLoop run_loop;
memory_instrumentation::MemoryInstrumentation::GetInstance() memory_instrumentation::MemoryInstrumentation::GetInstance()
->RequestGlobalDump(base::Bind( ->RequestGlobalDump(
[](base::Closure quit_closure, {}, base::Bind(
std::unique_ptr<GlobalMemoryDump>* out_result, bool success, [](base::Closure quit_closure,
std::unique_ptr<GlobalMemoryDump> result) { std::unique_ptr<GlobalMemoryDump>* out_result,
EXPECT_TRUE(success); bool success, std::unique_ptr<GlobalMemoryDump> result) {
*out_result = std::move(result); EXPECT_TRUE(success);
std::move(quit_closure).Run(); *out_result = std::move(result);
}, std::move(quit_closure).Run();
run_loop.QuitClosure(), &result)); },
run_loop.QuitClosure(), &result));
run_loop.Run(); run_loop.Run();
return result; return result;
} }
......
...@@ -120,7 +120,8 @@ void CoordinatorImpl::RequestGlobalMemoryDump( ...@@ -120,7 +120,8 @@ void CoordinatorImpl::RequestGlobalMemoryDump(
}; };
QueuedRequest::Args args(dump_type, level_of_detail, allocator_dump_names, QueuedRequest::Args args(dump_type, level_of_detail, allocator_dump_names,
false /* add_to_trace */, base::kNullProcessId); false /* add_to_trace */, base::kNullProcessId,
/*memory_footprint_only=*/false);
RequestGlobalMemoryDumpInternal(args, RequestGlobalMemoryDumpInternal(args,
base::BindOnce(adapter, std::move(callback))); base::BindOnce(adapter, std::move(callback)));
} }
...@@ -147,7 +148,27 @@ void CoordinatorImpl::RequestGlobalMemoryDumpForPid( ...@@ -147,7 +148,27 @@ void CoordinatorImpl::RequestGlobalMemoryDumpForPid(
QueuedRequest::Args args( QueuedRequest::Args args(
base::trace_event::MemoryDumpType::SUMMARY_ONLY, base::trace_event::MemoryDumpType::SUMMARY_ONLY,
base::trace_event::MemoryDumpLevelOfDetail::BACKGROUND, base::trace_event::MemoryDumpLevelOfDetail::BACKGROUND,
allocator_dump_names, false /* add_to_trace */, pid); allocator_dump_names, false /* add_to_trace */, pid,
/*memory_footprint_only=*/false);
RequestGlobalMemoryDumpInternal(args,
base::BindOnce(adapter, std::move(callback)));
}
void CoordinatorImpl::RequestPrivateMemoryFootprint(
base::ProcessId pid,
RequestPrivateMemoryFootprintCallback callback) {
// This merely strips out the |dump_guid| argument; this is not relevant
// as we are not adding to trace.
auto adapter = [](RequestPrivateMemoryFootprintCallback callback,
bool success, uint64_t,
mojom::GlobalMemoryDumpPtr global_memory_dump) {
std::move(callback).Run(success, std::move(global_memory_dump));
};
QueuedRequest::Args args(
base::trace_event::MemoryDumpType::SUMMARY_ONLY,
base::trace_event::MemoryDumpLevelOfDetail::BACKGROUND, {},
false /* add_to_trace */, pid, /*memory_footprint_only=*/true);
RequestGlobalMemoryDumpInternal(args, RequestGlobalMemoryDumpInternal(args,
base::BindOnce(adapter, std::move(callback))); base::BindOnce(adapter, std::move(callback)));
} }
...@@ -164,7 +185,8 @@ void CoordinatorImpl::RequestGlobalMemoryDumpAndAppendToTrace( ...@@ -164,7 +185,8 @@ void CoordinatorImpl::RequestGlobalMemoryDumpAndAppendToTrace(
}; };
QueuedRequest::Args args(dump_type, level_of_detail, {}, QueuedRequest::Args args(dump_type, level_of_detail, {},
true /* add_to_trace */, base::kNullProcessId); true /* add_to_trace */, base::kNullProcessId,
/*memory_footprint_only=*/false);
RequestGlobalMemoryDumpInternal(args, RequestGlobalMemoryDumpInternal(args,
base::BindOnce(adapter, std::move(callback))); base::BindOnce(adapter, std::move(callback)));
} }
......
...@@ -67,6 +67,9 @@ class CoordinatorImpl : public Coordinator, ...@@ -67,6 +67,9 @@ class CoordinatorImpl : public Coordinator,
base::ProcessId, base::ProcessId,
const std::vector<std::string>& allocator_dump_names, const std::vector<std::string>& allocator_dump_names,
RequestGlobalMemoryDumpForPidCallback) override; RequestGlobalMemoryDumpForPidCallback) override;
void RequestPrivateMemoryFootprint(
base::ProcessId,
RequestPrivateMemoryFootprintCallback) override;
void RequestGlobalMemoryDumpAndAppendToTrace( void RequestGlobalMemoryDumpAndAppendToTrace(
base::trace_event::MemoryDumpType, base::trace_event::MemoryDumpType,
base::trace_event::MemoryDumpLevelOfDetail, base::trace_event::MemoryDumpLevelOfDetail,
......
...@@ -10,12 +10,14 @@ QueuedRequest::Args::Args(MemoryDumpType dump_type, ...@@ -10,12 +10,14 @@ QueuedRequest::Args::Args(MemoryDumpType dump_type,
MemoryDumpLevelOfDetail level_of_detail, MemoryDumpLevelOfDetail level_of_detail,
const std::vector<std::string>& allocator_dump_names, const std::vector<std::string>& allocator_dump_names,
bool add_to_trace, bool add_to_trace,
base::ProcessId pid) base::ProcessId pid,
bool memory_footprint_only)
: dump_type(dump_type), : dump_type(dump_type),
level_of_detail(level_of_detail), level_of_detail(level_of_detail),
allocator_dump_names(allocator_dump_names), allocator_dump_names(allocator_dump_names),
add_to_trace(add_to_trace), add_to_trace(add_to_trace),
pid(pid) {} pid(pid),
memory_footprint_only(memory_footprint_only) {}
QueuedRequest::Args::Args(const Args& args) = default; QueuedRequest::Args::Args(const Args& args) = default;
QueuedRequest::Args::~Args() = default; QueuedRequest::Args::~Args() = default;
......
...@@ -33,7 +33,8 @@ struct QueuedRequest { ...@@ -33,7 +33,8 @@ struct QueuedRequest {
MemoryDumpLevelOfDetail level_of_detail, MemoryDumpLevelOfDetail level_of_detail,
const std::vector<std::string>& allocator_dump_names, const std::vector<std::string>& allocator_dump_names,
bool add_to_trace, bool add_to_trace,
base::ProcessId pid); base::ProcessId pid,
bool memory_footprint_only);
Args(const Args&); Args(const Args&);
~Args(); ~Args();
...@@ -42,6 +43,10 @@ struct QueuedRequest { ...@@ -42,6 +43,10 @@ struct QueuedRequest {
const std::vector<std::string> allocator_dump_names; const std::vector<std::string> allocator_dump_names;
const bool add_to_trace; const bool add_to_trace;
const base::ProcessId pid; const base::ProcessId pid;
// If this member is |true|, then no MemoryDumpProviders are queried. The
// only other relevant member is |pid|.
const bool memory_footprint_only;
}; };
struct PendingResponse { struct PendingResponse {
......
...@@ -216,18 +216,20 @@ void QueuedRequestDispatcher::SetUpAndDispatch( ...@@ -216,18 +216,20 @@ void QueuedRequestDispatcher::SetUpAndDispatch(
request->responses[client].process_id = client_info.pid; request->responses[client].process_id = client_info.pid;
request->responses[client].process_type = client_info.process_type; request->responses[client].process_type = client_info.process_type;
// Don't request a chrome memory dump at all if the client wants only the // Don't request a chrome memory dump at all if the client only wants the
// processes' vm regions, which are retrieved via RequestOSMemoryDump(). // a memory footprint.
// //
// This must occur before the call to RequestOSMemoryDump, as // This must occur before the call to RequestOSMemoryDump, as
// ClientProcessImpl will [for macOS], delay the calculations for the // ClientProcessImpl will [for macOS], delay the calculations for the
// OSMemoryDump until the Chrome memory dump is finished. See // OSMemoryDump until the Chrome memory dump is finished. See
// https://bugs.chromium.org/p/chromium/issues/detail?id=812346#c16 for more // https://bugs.chromium.org/p/chromium/issues/detail?id=812346#c16 for more
// details. // details.
request->pending_responses.insert({client, ResponseType::kChromeDump}); if (!request->args.memory_footprint_only) {
client->RequestChromeMemoryDump( request->pending_responses.insert({client, ResponseType::kChromeDump});
request->GetRequestArgs(), client->RequestChromeMemoryDump(
base::BindOnce(std::move(chrome_callback), client)); request->GetRequestArgs(),
base::BindOnce(std::move(chrome_callback), client));
}
// On most platforms each process can dump data about their own process // On most platforms each process can dump data about their own process
// so ask each process to do so Linux is special see below. // so ask each process to do so Linux is special see below.
...@@ -496,11 +498,16 @@ void QueuedRequestDispatcher::Finalize(QueuedRequest* request, ...@@ -496,11 +498,16 @@ void QueuedRequestDispatcher::Finalize(QueuedRequest* request,
} }
} }
// Ignore incomplete results (can happen if the client crashes/disconnects). bool valid = false;
const bool valid = if (request->args.memory_footprint_only) {
raw_os_dump && raw_chrome_dump && valid = raw_os_dump;
(request->memory_map_option() == mojom::MemoryMapOption::NONE || } else {
(raw_os_dump && !raw_os_dump->memory_maps.empty())); // Ignore incomplete results (can happen if the client
// crashes/disconnects).
valid = raw_os_dump && raw_chrome_dump &&
(request->memory_map_option() == mojom::MemoryMapOption::NONE ||
(raw_os_dump && !raw_os_dump->memory_maps.empty()));
}
if (!valid) if (!valid)
continue; continue;
......
...@@ -51,11 +51,6 @@ MemoryInstrumentation::~MemoryInstrumentation() { ...@@ -51,11 +51,6 @@ MemoryInstrumentation::~MemoryInstrumentation() {
g_instance = nullptr; g_instance = nullptr;
} }
void MemoryInstrumentation::RequestGlobalDump(
RequestGlobalDumpCallback callback) {
RequestGlobalDump({}, callback);
}
void MemoryInstrumentation::RequestGlobalDump( void MemoryInstrumentation::RequestGlobalDump(
const std::vector<std::string>& allocator_dump_names, const std::vector<std::string>& allocator_dump_names,
RequestGlobalDumpCallback callback) { RequestGlobalDumpCallback callback) {
...@@ -66,10 +61,12 @@ void MemoryInstrumentation::RequestGlobalDump( ...@@ -66,10 +61,12 @@ void MemoryInstrumentation::RequestGlobalDump(
base::BindRepeating(&WrapGlobalMemoryDump, callback)); base::BindRepeating(&WrapGlobalMemoryDump, callback));
} }
void MemoryInstrumentation::RequestGlobalDumpForPid( void MemoryInstrumentation::RequestPrivateMemoryFootprint(
base::ProcessId pid, base::ProcessId pid,
RequestGlobalDumpCallback callback) { RequestGlobalDumpCallback callback) {
RequestGlobalDumpForPid(pid, {}, callback); const auto& coordinator = GetCoordinatorBindingForCurrentThread();
coordinator->RequestPrivateMemoryFootprint(
pid, base::BindRepeating(&WrapGlobalMemoryDump, callback));
} }
void MemoryInstrumentation::RequestGlobalDumpForPid( void MemoryInstrumentation::RequestGlobalDumpForPid(
......
...@@ -40,16 +40,6 @@ class SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_EXPORT MemoryInstrumentation { ...@@ -40,16 +40,6 @@ class SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_EXPORT MemoryInstrumentation {
const std::string& service_name); const std::string& service_name);
static MemoryInstrumentation* GetInstance(); static MemoryInstrumentation* GetInstance();
// Requests a global memory dump.
// Returns asynchronously, via the callback argument:
// (true, global_dump) if succeeded;
// (false, nullptr) if failed.
// The callback (if not null), will be posted on the same thread of the
// RequestGlobalDump() call.
// TODO(lalitm): this is temporary until we migrate task manager, metrics
// etc to use the new method.
void RequestGlobalDump(RequestGlobalDumpCallback);
// Requests a global memory dump with |allocator_dump_names| indicating // Requests a global memory dump with |allocator_dump_names| indicating
// the name of allocator dumps in which the consumer is interested. If // the name of allocator dumps in which the consumer is interested. If
// |allocator_dump_names| is empty, no dumps will be returned. // |allocator_dump_names| is empty, no dumps will be returned.
...@@ -59,16 +49,21 @@ class SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_EXPORT MemoryInstrumentation { ...@@ -59,16 +49,21 @@ class SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_EXPORT MemoryInstrumentation {
// but missing data. // but missing data.
// The callback (if not null), will be posted on the same thread of the // The callback (if not null), will be posted on the same thread of the
// RequestGlobalDump() call. // RequestGlobalDump() call.
// Note: Even if |allocator_dump_names| is empty, all MemoryDumpProviders will
// still be queried.
void RequestGlobalDump(const std::vector<std::string>& allocator_dump_names, void RequestGlobalDump(const std::vector<std::string>& allocator_dump_names,
RequestGlobalDumpCallback); RequestGlobalDumpCallback);
// Requests a global memory dump. // Returns asynchronously, via the callback argument:
// Returns asynchronously, via the callback argument, the global memory // (true, global_dump) if succeeded;
// dump with the process memory dump for the given pid or null if the dump // (false, global_dump) if failed, with global_dump being non-null
// failed. // but missing data.
// The callback (if not null), will be posted on the same thread of the // The callback (if not null), will be posted on the same thread of the
// RequestGlobalDumpForPid() call. // RequestPrivateMemoryFootprint() call.
void RequestGlobalDumpForPid(base::ProcessId pid, RequestGlobalDumpCallback); // Passing a null |pid| is the same as requesting the PrivateMemoryFootprint
// for all processes.
void RequestPrivateMemoryFootprint(base::ProcessId pid,
RequestGlobalDumpCallback);
// Requests a global memory dump with |allocator_dump_names| indicating // Requests a global memory dump with |allocator_dump_names| indicating
// the name of allocator dumps in which the consumer is interested. If // the name of allocator dumps in which the consumer is interested. If
......
...@@ -123,6 +123,10 @@ class MockCoordinator : public Coordinator, public mojom::Coordinator { ...@@ -123,6 +123,10 @@ class MockCoordinator : public Coordinator, public mojom::Coordinator {
const std::vector<std::string>& allocator_dump_names, const std::vector<std::string>& allocator_dump_names,
RequestGlobalMemoryDumpForPidCallback) override {} RequestGlobalMemoryDumpForPidCallback) override {}
void RequestPrivateMemoryFootprint(
base::ProcessId pid,
RequestPrivateMemoryFootprintCallback) override {}
void RequestGlobalMemoryDumpAndAppendToTrace( void RequestGlobalMemoryDumpAndAppendToTrace(
MemoryDumpType dump_type, MemoryDumpType dump_type,
MemoryDumpLevelOfDetail level_of_detail, MemoryDumpLevelOfDetail level_of_detail,
......
...@@ -279,6 +279,12 @@ interface Coordinator { ...@@ -279,6 +279,12 @@ interface Coordinator {
array<string> allocator_dump_names) => array<string> allocator_dump_names) =>
(bool success, GlobalMemoryDump? global_memory_dump); (bool success, GlobalMemoryDump? global_memory_dump);
// Requesting a null pid is the same as requesting all pids.
// The returned dump only contains OS metrics. |chrome_allocator_dumps| will
// be empty.
RequestPrivateMemoryFootprint(mojo_base.mojom.ProcessId pid) =>
(bool success, GlobalMemoryDump? global_memory_dump);
// Broadcasts a dump request to all registered client processes and injects the // Broadcasts a dump request to all registered client processes and injects the
// dump in the trace buffer (if tracing is enabled). // dump in the trace buffer (if tracing is enabled).
RequestGlobalMemoryDumpAndAppendToTrace(DumpType dump_type, RequestGlobalMemoryDumpAndAppendToTrace(DumpType dump_type,
......
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