| Index: components/tracing/docs/adding_memory_infra_tracing.md
|
| diff --git a/components/tracing/docs/adding_memory_infra_tracing.md b/components/tracing/docs/adding_memory_infra_tracing.md
|
| index 7960e153dd1800335bd0a102dda9a6897e19db26..ea01fa7e21356533738efc06305ca26e724fc489 100644
|
| --- a/components/tracing/docs/adding_memory_infra_tracing.md
|
| +++ b/components/tracing/docs/adding_memory_infra_tracing.md
|
| @@ -1,178 +1,2 @@
|
| -# Adding MemoryInfra Tracing to a Component
|
| +This document has moved to [//docs/memory-infra/adding_memory_infra_tracing.md](/docs/memory-infra/adding_memory_infra_tracing.md).
|
|
|
| -If you have a component that manages memory allocations, you should be
|
| -registering and tracking those allocations with Chrome's MemoryInfra system.
|
| -This lets you:
|
| -
|
| - * See an overview of your allocations, giving insight into total size and
|
| - breakdown.
|
| - * Understand how your allocations change over time and how they are impacted by
|
| - other parts of Chrome.
|
| - * Catch regressions in your component's allocations size by setting up
|
| - telemetry tests which monitor your allocation sizes under certain
|
| - circumstances.
|
| -
|
| -Some existing components that use MemoryInfra:
|
| -
|
| - * **Discardable Memory**: Tracks usage of discardable memory throughout Chrome.
|
| - * **GPU**: Tracks OpenGL and other GPU object allocations.
|
| - * **V8**: Tracks the heap size for JS.
|
| -
|
| -[TOC]
|
| -
|
| -## Overview
|
| -
|
| -In order to hook into Chrome's MemoryInfra system, your component needs to do
|
| -two things:
|
| -
|
| - 1. Create a [`MemoryDumpProvider`][mdp] for your component.
|
| - 2. Register and unregister you dump provider with the
|
| - [`MemoryDumpManager`][mdm].
|
| -
|
| -[mdp]: https://chromium.googlesource.com/chromium/src/+/master/base/trace_event/memory_dump_provider.h
|
| -[mdm]: https://chromium.googlesource.com/chromium/src/+/master/base/trace_event/memory_dump_manager.h
|
| -
|
| -## Creating a Memory Dump Provider
|
| -
|
| -You can implement a [`MemoryDumpProvider`][mdp] as a stand-alone class, or as an
|
| -additional interface on an existing class. For example, this interface is
|
| -frequently implemented on classes which manage a pool of allocations (see
|
| -[`cc::ResourcePool`][resource-pool] for an example).
|
| -
|
| -A `MemoryDumpProvider` has one basic job, to implement `OnMemoryDump`. This
|
| -function is responsible for iterating over the resources allocated or tracked by
|
| -your component, and creating a [`MemoryAllocatorDump`][mem-alloc-dump] for each
|
| -using [`ProcessMemoryDump::CreateAllocatorDump`][pmd]. A simple example:
|
| -
|
| -```cpp
|
| -bool MyComponent::OnMemoryDump(const MemoryDumpArgs& args,
|
| - ProcessMemoryDump* process_memory_dump) {
|
| - for (const auto& allocation : my_allocations_) {
|
| - auto* dump = process_memory_dump->CreateAllocatorDump(
|
| - "path/to/my/component/allocation_" + allocation.id().ToString());
|
| - dump->AddScalar(base::trace_event::MemoryAllocatorDump::kNameSize,
|
| - base::trace_event::MemoryAllocatorDump::kUnitsBytes,
|
| - allocation.size_bytes());
|
| -
|
| - // While you will typically have a kNameSize entry, you can add additional
|
| - // entries to your dump with free-form names. In this example we also dump
|
| - // an object's "free_size", assuming the object may not be entirely in use.
|
| - dump->AddScalar("free_size",
|
| - base::trace_event::MemoryAllocatorDump::kUnitsBytes,
|
| - allocation.free_size_bytes());
|
| - }
|
| -}
|
| -```
|
| -
|
| -For many components, this may be all that is needed. See
|
| -[Handling Shared Memory Allocations](#Handling-Shared-Memory-Allocations) and
|
| -[Suballocations](#Suballocations) for information on more complex use cases.
|
| -
|
| -[resource-pool]: https://chromium.googlesource.com/chromium/src/+/master/cc/resources/resource_pool.h
|
| -[mem-alloc-dump]: https://chromium.googlesource.com/chromium/src/+/master/base/trace_event/memory_allocator_dump.h
|
| -[pmd]: https://chromium.googlesource.com/chromium/src/+/master/base/trace_event/process_memory_dump.h
|
| -
|
| -## Registering a Memory Dump Provider
|
| -
|
| -Once you have created a [`MemoryDumpProvider`][mdp], you need to register it
|
| -with the [`MemoryDumpManager`][mdm] before the system can start polling it for
|
| -memory information. Registration is generally straightforward, and involves
|
| -calling `MemoryDumpManager::RegisterDumpProvider`:
|
| -
|
| -```cpp
|
| -// Each process uses a singleton |MemoryDumpManager|.
|
| -base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
|
| - my_memory_dump_provider_, my_single_thread_task_runner_);
|
| -```
|
| -
|
| -In the above code, `my_memory_dump_provider_` is the `MemoryDumpProvider`
|
| -outlined in the previous section. `my_single_thread_task_runner_` is more
|
| -complex and may be a number of things:
|
| -
|
| - * Most commonly, if your component is always used from the main message loop,
|
| - `my_single_thread_task_runner_` may just be
|
| - [`base::ThreadTaskRunnerHandle::Get()`][task-runner-handle].
|
| - * If your component already uses a custom `base::SingleThreadTaskRunner` for
|
| - executing tasks on a specific thread, you should likely use this runner.
|
| -
|
| -[task-runner-handle]: https://chromium.googlesource.com/chromium/src/+/master/base/thread_task_runner_handle.h
|
| -
|
| -## Unregistration
|
| -
|
| -Unregistration must happen on the thread belonging to the
|
| -`SingleThreadTaskRunner` provided at registration time. Unregistering on another
|
| -thread can lead to race conditions if tracing is active when the provider is
|
| -unregistered.
|
| -
|
| -```cpp
|
| -base::trace_event::MemoryDumpManager::GetInstance()->UnregisterDumpProvider(
|
| - my_memory_dump_provider_);
|
| -```
|
| -
|
| -## Handling Shared Memory Allocations
|
| -
|
| -When an allocation is shared between two components, it may be useful to dump
|
| -the allocation in both components, but you also want to avoid double-counting
|
| -the allocation. This can be achieved using the concept of _ownership edges_.
|
| -An ownership edge represents that the _source_ memory allocator dump owns a
|
| -_target_ memory allocator dump. If multiple source dumps own a single target,
|
| -then the cost of that target allocation will be split between the sources.
|
| -Additionally, importance can be added to a specific ownership edge, allowing
|
| -the highest importance source of that edge to claim the entire cost of the
|
| -target.
|
| -
|
| -In the typical case, you will use [`ProcessMemoryDump`][pmd] to create a shared
|
| -global allocator dump. This dump will act as the target of all
|
| -component-specific dumps of a specific resource:
|
| -
|
| -```cpp
|
| -// Component 1 is going to create a dump, source_mad, for an allocation,
|
| -// alloc_, which may be shared with other components / processes.
|
| -MyAllocationType* alloc_;
|
| -base::trace_event::MemoryAllocatorDump* source_mad;
|
| -
|
| -// Component 1 creates and populates source_mad;
|
| -...
|
| -
|
| -// In addition to creating a source dump, we must create a global shared
|
| -// target dump. This dump should be created with a unique global ID which can be
|
| -// generated any place the allocation is used. I recommend adding a global ID
|
| -// generation function to the allocation type.
|
| -base::trace_event::MemoryAllocatorDumpGUID guid(alloc_->GetGUIDString());
|
| -
|
| -// From this global ID we can generate the parent allocator dump.
|
| -base::trace_event::MemoryAllocatorDump* target_mad =
|
| - process_memory_dump->CreateSharedGlobalAllocatorDump(guid);
|
| -
|
| -// We now create an ownership edge from the source dump to the target dump.
|
| -// When creating an edge, you can assign an importance to this edge. If all
|
| -// edges have the same importance, the size of the allocation will be split
|
| -// between all sources which create a dump for the allocation. If one
|
| -// edge has higher importance than the others, its source will be assigned the
|
| -// full size of the allocation.
|
| -const int kImportance = 1;
|
| -process_memory_dump->AddOwnershipEdge(
|
| - source_mad->guid(), target_mad->guid(), kImportance);
|
| -```
|
| -
|
| -If an allocation is being shared across process boundaries, it may be useful to
|
| -generate a global ID which incorporates the ID of the local process, preventing
|
| -two processes from generating colliding IDs. As it is not recommended to pass a
|
| -process ID between processes for security reasons, a function
|
| -`MemoryDumpManager::GetTracingProcessId` is provided which generates a unique ID
|
| -per process that can be passed with the resource without security concerns.
|
| -Frequently this ID is used to generate a global ID that is based on the
|
| -allocated resource's ID combined with the allocating process' tracing ID.
|
| -
|
| -## Suballocations
|
| -
|
| -Another advanced use case involves tracking sub-allocations of a larger
|
| -allocation. For instance, this is used in
|
| -[`gpu::gles2::TextureManager`][texture-manager] to dump both the suballocations
|
| -which make up a texture. To create a suballocation, instead of calling
|
| -[`ProcessMemoryDump::CreateAllocatorDump`][pmd] to create a
|
| -[`MemoryAllocatorDump`][mem-alloc-dump], you call
|
| -[`ProcessMemoryDump::AddSubAllocation`][pmd], providing the ID of the parent
|
| -allocation as the first parameter.
|
| -
|
| -[texture-manager]: https://chromium.googlesource.com/chromium/src/+/master/gpu/command_buffer/service/texture_manager.cc
|
|
|