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

Unified Diff: components/tracing/docs/heap_profiler_internals.md

Issue 2494063002: Move memory docs to docs/memory-infra (Closed)
Patch Set: rebase Created 4 years, 1 month 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
« no previous file with comments | « components/tracing/docs/heap_profiler.md ('k') | components/tracing/docs/memory_infra.md » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: components/tracing/docs/heap_profiler_internals.md
diff --git a/components/tracing/docs/heap_profiler_internals.md b/components/tracing/docs/heap_profiler_internals.md
index d1019c8d2126b02dce0dbb01222a72a4f45496f9..a54e7f307101d355955cef5f38a27c10c95d1d2e 100644
--- a/components/tracing/docs/heap_profiler_internals.md
+++ b/components/tracing/docs/heap_profiler_internals.md
@@ -1,184 +1,2 @@
-# Heap Profiler Internals
+This document has moved to [//docs/memory-infra/heap_profiler_internals.md](/docs/memory-infra/heap_profiler_internals.md).
-This document describes how the heap profiler works and how to add heap
-profiling support to your allocator. If you just want to know how to use it,
-see [Heap Profiling with MemoryInfra](heap_profiler.md)
-
-[TOC]
-
-## Overview
-
-The heap profiler consists of tree main components:
-
- * **The Context Tracker**: Responsible for providing context (pseudo stack
- backtrace) when an allocation occurs.
- * **The Allocation Register**: A specialized hash table that stores allocation
- details by address.
- * **The Heap Dump Writer**: Extracts the most important information from a set
- of recorded allocations and converts it into a format that can be dumped into
- the trace log.
-
-These components are designed to work well together, but to be usable
-independently as well.
-
-When there is a way to get notified of all allocations and frees, this is the
-normal flow:
-
- 1. When an allocation occurs, call
- [`AllocationContextTracker::GetInstanceForCurrentThread()->GetContextSnapshot()`][context-tracker]
- to get an [`AllocationContext`][alloc-context].
- 2. Insert that context together with the address and size into an
- [`AllocationRegister`][alloc-register] by calling `Insert()`.
- 3. When memory is freed, remove it from the register with `Remove()`.
- 4. On memory dump, collect the allocations from the register, call
- [`ExportHeapDump()`][export-heap-dump], and add the generated heap dump to
- the memory dump.
-
-[context-tracker]: https://chromium.googlesource.com/chromium/src/+/master/base/trace_event/heap_profiler_allocation_context_tracker.h
-[alloc-context]: https://chromium.googlesource.com/chromium/src/+/master/base/trace_event/heap_profiler_allocation_context.h
-[alloc-register]: https://chromium.googlesource.com/chromium/src/+/master/base/trace_event/heap_profiler_allocation_register.h
-[export-heap-dump]: https://chromium.googlesource.com/chromium/src/+/master/base/trace_event/heap_profiler_heap_dump_writer.h
-
-*** aside
-An allocator can skip step 2 and 3 if it is able to store the context itself,
-and if it is able to enumerate all allocations for step 4.
-***
-
-When heap profiling is enabled (the `--enable-heap-profiling` flag is passed),
-the memory dump manager calls `OnHeapProfilingEnabled()` on every
-`MemoryDumpProvider` as early as possible, so allocators can start recording
-allocations. This should be done even when tracing has not been started,
-because these allocations might still be around when a heap dump happens during
-tracing.
-
-## Context Tracker
-
-The [`AllocationContextTracker`][context-tracker] is a thread-local object. Its
-main purpose is to keep track of a pseudo stack of trace events. Chrome has
-been instrumented with lots of `TRACE_EVENT` macros. These trace events push
-their name to a thread-local stack when they go into scope, and pop when they
-go out of scope, if all of the following conditions have been met:
-
- * A trace is being recorded.
- * The category of the event is enabled in the trace config.
- * Heap profiling is enabled (with the `--enable-heap-profiling` flag).
-
-This means that allocations that occur before tracing is started will not have
-backtrace information in their context.
-
-A thread-local instance of the context tracker is initialized lazily when it is
-first accessed. This might be because a trace event pushed or popped, or because
-`GetContextSnapshot()` was called when an allocation occurred.
-
-[`AllocationContext`][alloc-context] is what is used to group and break down
-allocations. Currently `AllocationContext` has the following fields:
-
- * Backtrace: filled by the context tracker, obtained from the thread-local
- pseudo stack.
- * Type name: to be filled in at a point where the type of a pointer is known,
- set to _[unknown]_ by default.
-
-It is possible to modify this context after insertion into the register, for
-instance to set the type name if it was not known at the time of allocation.
-
-## Allocation Register
-
-The [`AllocationRegister`][alloc-register] is a hash table specialized for
-storing `(size, AllocationContext)` pairs by address. It has been optimized for
-Chrome's typical number of unfreed allocations, and it is backed by `mmap`
-memory directly so there are no reentrancy issues when using it to record
-`malloc` allocations.
-
-The allocation register is threading-agnostic. Access must be synchronised
-properly.
-
-## Heap Dump Writer
-
-Dumping every single allocation in the allocation register straight into the
-trace log is not an option due to the sheer volume (~300k unfreed allocations).
-The role of the [`ExportHeapDump()`][export-heap-dump] function is to group
-allocations, striking a balance between trace log size and detail.
-
-See the [Heap Dump Format][heap-dump-format] document for more details about the
-structure of the heap dump in the trace log.
-
-[heap-dump-format]: https://docs.google.com/document/d/1NqBg1MzVnuMsnvV1AKLdKaPSPGpd81NaMPVk5stYanQ
-
-## Instrumenting an Allocator
-
-Below is an example of adding heap profiling support to an allocator that has
-an existing memory dump provider.
-
-```cpp
-class FooDumpProvider : public MemoryDumpProvider {
-
- // Kept as pointer because |AllocationRegister| allocates a lot of virtual
- // address space when constructed, so only construct it when heap profiling is
- // enabled.
- scoped_ptr<AllocationRegister> allocation_register_;
- Lock allocation_register_lock_;
-
- static FooDumpProvider* GetInstance();
-
- void InsertAllocation(void* address, size_t size) {
- AllocationContext context = AllocationContextTracker::GetInstanceForCurrentThread()->GetContextSnapshot();
- AutoLock lock(allocation_register_lock_);
- allocation_register_->Insert(address, size, context);
- }
-
- void RemoveAllocation(void* address) {
- AutoLock lock(allocation_register_lock_);
- allocation_register_->Remove(address);
- }
-
- // Will be called as early as possible by the memory dump manager.
- void OnHeapProfilingEnabled(bool enabled) override {
- AutoLock lock(allocation_register_lock_);
- allocation_register_.reset(new AllocationRegister());
-
- // At this point, make sure that from now on, for every allocation and
- // free, |FooDumpProvider::GetInstance()->InsertAllocation()| and
- // |RemoveAllocation| are called.
- }
-
- bool OnMemoryDump(const MemoryDumpArgs& args,
- ProcessMemoryDump& pmd) override {
- // Do regular dumping here.
-
- // Dump the heap only for detailed dumps.
- if (args.level_of_detail == MemoryDumpLevelOfDetail::DETAILED) {
- TraceEventMemoryOverhead overhead;
- hash_map<AllocationContext, size_t> bytes_by_context;
-
- {
- AutoLock lock(allocation_register_lock_);
- if (allocation_register_) {
- // Group allocations in the register into |bytes_by_context|, but do
- // no additional processing inside the lock.
- for (const auto& alloc_size : *allocation_register_)
- bytes_by_context[alloc_size.context] += alloc_size.size;
-
- allocation_register_->EstimateTraceMemoryOverhead(&overhead);
- }
- }
-
- if (!bytes_by_context.empty()) {
- scoped_refptr<TracedValue> heap_dump = ExportHeapDump(
- bytes_by_context,
- pmd->session_state()->stack_frame_deduplicator(),
- pmb->session_state()->type_name_deduplicator());
- pmd->AddHeapDump("foo_allocator", heap_dump);
- overhead.DumpInto("tracing/heap_profiler", pmd);
- }
- }
-
- return true;
- }
-};
-
-```
-
-*** aside
-The implementation for `malloc` is more complicated because it needs to deal
-with reentrancy.
-***
« no previous file with comments | « components/tracing/docs/heap_profiler.md ('k') | components/tracing/docs/memory_infra.md » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698