Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(185)

Unified Diff: services/resource_coordinator/memory/coordinator/coordinator_impl.cc

Issue 2883693002: [Memory-UMA] Implement basic working prototype. (Closed)
Patch Set: Tests working. Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: services/resource_coordinator/memory/coordinator/coordinator_impl.cc
diff --git a/services/resource_coordinator/memory/coordinator/coordinator_impl.cc b/services/resource_coordinator/memory/coordinator/coordinator_impl.cc
index 4cc1840ba72ab45b937cd767787ea13942f9bf9a..a9c8960dff4d450a7213c93b4c48f0e834a15747 100644
--- a/services/resource_coordinator/memory/coordinator/coordinator_impl.cc
+++ b/services/resource_coordinator/memory/coordinator/coordinator_impl.cc
@@ -16,11 +16,42 @@
#include "services/resource_coordinator/public/cpp/memory/process_local_dump_manager_impl.h"
#include "services/resource_coordinator/public/interfaces/memory/constants.mojom.h"
#include "services/resource_coordinator/public/interfaces/memory/memory_instrumentation.mojom.h"
+#include "services/service_manager/public/cpp/connector.h"
+#include "services/service_manager/public/cpp/identity.h"
+#include "services/service_manager/public/interfaces/constants.mojom.h"
+#include "services/service_manager/public/interfaces/service_manager.mojom.h"
+
+#if defined(OS_MACOSX) && !defined(OS_IOS)
+#include "base/mac/mac_util.h"
+#endif
namespace {
memory_instrumentation::CoordinatorImpl* g_coordinator_impl;
+uint32_t CalculatePrivateFootprintKb(
+ base::trace_event::MemoryDumpCallbackResult::OSMemDump& os_dump) {
+#if defined(OS_LINUX) || defined(OS_ANDROID)
+ uint64_t rss_anon_bytes = os_dump.platform_private_footprint.rss_anon_bytes;
+ uint64_t vm_swap_bytes = os_dump.platform_private_footprint.vm_swap_bytes;
+ return (rss_anon_bytes + vm_swap_bytes) / 1024;
+#elif defined(OS_MACOSX)
+ // TODO(erikchen): This calculation is close, but not fully accurate. It
+ // overcounts by anonymous shared memory.
+ if (base::mac::IsAtLeastOS10_12()) {
+ uint64_t phys_footprint_bytes =
+ os_dump.platform_private_footprint.phys_footprint_bytes;
+ return phys_footprint_bytes / 1024;
+ } else {
+ uint64_t internal_bytes = os_dump.platform_private_footprint.internal_bytes;
+ uint64_t compressed_bytes =
+ os_dump.platform_private_footprint.compressed_bytes;
+ return (internal_bytes + compressed_bytes) / 1024;
+ }
+#endif
+ return 0;
dcheng 2017/05/13 20:22:37 I'm kind of surprised that there's no compiler war
erikchen 2017/05/14 04:49:16 Done.
+}
+
} // namespace
namespace memory_instrumentation {
@@ -30,9 +61,12 @@ CoordinatorImpl* CoordinatorImpl::GetInstance() {
return g_coordinator_impl;
}
-CoordinatorImpl::CoordinatorImpl(bool initialize_memory_dump_manager)
+CoordinatorImpl::CoordinatorImpl(bool initialize_memory_dump_manager,
+ service_manager::Connector* connector,
+ bool initialize_process_map)
: failed_memory_dump_count_(0),
- initialize_memory_dump_manager_(initialize_memory_dump_manager) {
+ initialize_memory_dump_manager_(initialize_memory_dump_manager),
+ process_map_(nullptr) {
dcheng 2017/05/13 20:22:37 Nit: the default ctor does this, no need to explic
erikchen 2017/05/14 04:49:16 Done.
if (initialize_memory_dump_manager) {
// TODO(primiano): the current state where the coordinator also creates a
// client (ProcessLocalDumpManagerImpl) is contra-intuitive. BrowserMainLoop
@@ -42,9 +76,15 @@ CoordinatorImpl::CoordinatorImpl(bool initialize_memory_dump_manager)
base::trace_event::MemoryDumpManager::GetInstance()->set_tracing_process_id(
mojom::kServiceTracingProcessId);
}
+ if (initialize_process_map)
+ InitProcessMap(connector);
g_coordinator_impl = this;
}
+service_manager::Identity CoordinatorImpl::GetDispatchContext() const {
+ return bindings_.dispatch_context();
+}
+
CoordinatorImpl::~CoordinatorImpl() {
g_coordinator_impl = nullptr;
}
@@ -53,7 +93,7 @@ void CoordinatorImpl::BindCoordinatorRequest(
const service_manager::BindSourceInfo& source_info,
mojom::CoordinatorRequest request) {
DCHECK(thread_checker_.CalledOnValidThread());
- bindings_.AddBinding(this, std::move(request));
+ bindings_.AddBinding(this, std::move(request), source_info.identity);
}
CoordinatorImpl::QueuedMemoryDumpRequest::QueuedMemoryDumpRequest(
@@ -74,7 +114,8 @@ void CoordinatorImpl::RequestGlobalMemoryDump(
// point in enqueuing this request.
if (another_dump_already_in_progress &&
args.dump_type !=
- base::trace_event::MemoryDumpType::EXPLICITLY_TRIGGERED) {
+ base::trace_event::MemoryDumpType::EXPLICITLY_TRIGGERED &&
+ args.dump_type != base::trace_event::MemoryDumpType::SUMMARY_ONLY) {
for (const auto& request : queued_memory_dump_requests_) {
if (request.args.level_of_detail == args.level_of_detail) {
VLOG(1) << base::trace_event::MemoryDumpManager::kLogPrefix << " ("
@@ -107,10 +148,9 @@ void CoordinatorImpl::RegisterProcessLocalDumpManager(
process_manager.set_connection_error_handler(
base::Bind(&CoordinatorImpl::UnregisterProcessLocalDumpManager,
base::Unretained(this), process_manager.get()));
- auto result = process_managers_.insert(
- std::make_pair<mojom::ProcessLocalDumpManager*,
- mojom::ProcessLocalDumpManagerPtr>(
- process_manager.get(), std::move(process_manager)));
+ auto result = process_managers_.insert(std::make_pair(
dcheng 2017/05/13 20:22:37 Nit: consider using emplace() here to get rid of o
erikchen 2017/05/14 04:49:16 Done.
+ process_manager.get(),
+ std::make_pair(std::move(process_manager), GetDispatchContext())));
DCHECK(result.second);
}
@@ -135,15 +175,15 @@ void CoordinatorImpl::PerformNextQueuedGlobalMemoryDump() {
queued_memory_dump_requests_.front().args;
// No need to treat the service process different than other processes. The
- // service process will register itself as a ProcessLocalDumpManager and will
- // be treated like other process-local managers.
+ // service process will register itself as a ProcessLocalDumpManager and
+ // will be treated like other process-local managers.
pending_process_managers_.clear();
failed_memory_dump_count_ = 0;
for (const auto& key_value : process_managers_) {
pending_process_managers_.insert(key_value.first);
auto callback = base::Bind(&CoordinatorImpl::OnProcessMemoryDumpResponse,
base::Unretained(this), key_value.first);
- key_value.second->RequestProcessMemoryDump(args, callback);
+ key_value.second.first->RequestProcessMemoryDump(args, callback);
}
// Run the callback in case there are no process-local managers.
FinalizeGlobalMemoryDumpIfAllManagersReplied();
@@ -163,8 +203,14 @@ void CoordinatorImpl::OnProcessMemoryDumpResponse(
return;
}
if (process_memory_dump) {
+ base::ProcessId pid = base::kNullProcessId;
+ auto it = process_managers_.find(process_manager);
+ if (it != process_managers_.end()) {
+ pid = process_map_->GetProcessId(it->second.second);
+ }
+
queued_memory_dump_requests_.front().process_memory_dumps.push_back(
- std::move(process_memory_dump));
+ std::make_pair(pid, std::move(process_memory_dump)));
}
pending_process_managers_.erase(it);
@@ -187,15 +233,49 @@ void CoordinatorImpl::FinalizeGlobalMemoryDumpIfAllManagersReplied() {
return;
}
- // TODO(hjd,fmeawad): At this point the |process_memory_dumps| accumulated in
- // queued_memory_dump_requests_.front() should be normalized (merge
- // |extra_process_dump|, compute CMM) into a GlobalMemoryDumpPtr and passed
- // below.
+ std::map<base::ProcessId, mojom::ProcessMemoryDumpPtr> finalized_pmds;
+ for (auto& result :
+ queued_memory_dump_requests_.front().process_memory_dumps) {
+ mojom::ProcessMemoryDumpPtr& pmd = finalized_pmds[result.first];
+ if (!pmd)
+ pmd = mojom::ProcessMemoryDump::New();
+ pmd->chrome_dump = std::move(result.second->chrome_dump);
dcheng 2017/05/13 20:22:37 Nit: #include <utility>
erikchen 2017/05/14 04:49:16 Done.
+
+ // TODO(hjd): We should have a better way to tell if os_dump is filled.
+ if (result.second->os_dump.resident_set_kb > 0) {
+ pmd->os_dump = std::move(result.second->os_dump);
+ }
+
+ for (auto& pair : result.second->extra_processes_dump) {
+ base::ProcessId pid = pair.first;
+ mojom::ProcessMemoryDumpPtr& pmd = finalized_pmds[pid];
+ if (!pmd)
+ pmd = mojom::ProcessMemoryDump::New();
+ pmd->os_dump = std::move(result.second->extra_processes_dump[pid]);
+ }
+
+ pmd->process_type = result.second->process_type;
+ }
+
+ mojom::GlobalMemoryDumpPtr global_dump(mojom::GlobalMemoryDump::New());
+ for (auto& pair : finalized_pmds) {
+ // It's possible that the renderer has died but we still have an os_dump,
+ // because those were comptued from the browser proces before the renderer
dcheng 2017/05/13 20:22:37 Nit: computed
erikchen 2017/05/14 04:49:16 Done.
+ // died. We should skip these.
+ // TODO(hjd): We should have a better way to tell if a chrome_dump is
+ // filled.
+ if (!pair.second->chrome_dump.malloc_total_kb)
+ continue;
+ base::ProcessId pid = pair.first;
+ mojom::ProcessMemoryDumpPtr pmd = std::move(finalized_pmds[pid]);
dcheng 2017/05/13 20:22:37 Nit: Maybe just alias this instead of double movin
erikchen 2017/05/14 04:49:16 Done.
+ pmd->private_footprint = CalculatePrivateFootprintKb(pmd->os_dump);
+ global_dump->process_dumps.push_back(std::move(pmd));
+ }
const auto& callback = queued_memory_dump_requests_.front().callback;
const bool global_success = failed_memory_dump_count_ == 0;
callback.Run(queued_memory_dump_requests_.front().args.dump_guid,
- global_success, nullptr /* global_memory_dump */);
+ global_success, std::move(global_dump));
queued_memory_dump_requests_.pop_front();
// Schedule the next queued dump (if applicable).
@@ -207,4 +287,16 @@ void CoordinatorImpl::FinalizeGlobalMemoryDumpIfAllManagersReplied() {
}
}
+void CoordinatorImpl::InitProcessMap(service_manager::Connector* connector) {
+ service_manager::mojom::ServiceManagerPtr service_manager;
+ connector->BindInterface(service_manager::mojom::kServiceName,
+ &service_manager);
+ service_manager::mojom::ServiceManagerListenerPtr listener;
+ service_manager::mojom::ServiceManagerListenerRequest request(
+ mojo::MakeRequest(&listener));
+ service_manager->AddListener(std::move(listener));
+ process_map_.reset(new ProcessMap());
+ process_map_->BindRequest(std::move(request));
+}
+
} // namespace memory_instrumentation

Powered by Google App Engine
This is Rietveld 408576698