Skip to content

Commit

Permalink
Update the memory allocation docs and add DHAT docs (#5270)
Browse files Browse the repository at this point in the history
  • Loading branch information
gregtatum authored Dec 18, 2024
1 parent 95aa3e0 commit b03e0f4
Showing 1 changed file with 28 additions and 6 deletions.
34 changes: 28 additions & 6 deletions docs-user/memory-allocations.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
# Memory Allocations

The Firefox Profiler supports three different types of memory profiling
The Firefox Profiler supports different types of memory profiling

1. Memory Track
2. Native Allocations (experimental)
3. JavaScript Allocations (experimental)
2. Native Allocations
3. JavaScript Allocations
4. Valgrind DHAT Profiles

## Memory Track

Expand All @@ -14,9 +15,9 @@ The memory track graphs overall allocation and deallocation numbers over time fo

The graph visualization tracks the relative memory usage over the committed range of time. It's important to note that this is not absolute memory usage. The graph and numbers will change when committing a range selection.

## Native Memory Allocations (experimental)
## Native Memory Allocations

The profiler has experimental support for analyzing allocations in native code (C++ and Rust) via stack sampling. These features require Nightly. To follow along you can open this [example showing DevTools opening and closing](https://perfht.ml/2LKZsfY)
The profiler has support for analyzing allocations in native code (C++ and Rust) via stack sampling. These features require Nightly. To follow along you can open this [example showing DevTools opening and closing](https://perfht.ml/2LKZsfY)

The Native Allocations feature works by collecting the stack and size of memory allocations from native (C++ or Rust) code. It does not collect every allocation, but only samples a subset of them. The sampling is biased towards larger allocations and larger frees. Larger allocations are more likely show up in the profile, and will most likely be more representative of the actual memory usage. Keep in mind that since these allocations are only sampled, not all allocations will be recorded. This means that memory track (the orange graph at the top) will most likely report different numbers for memory usage.

Expand Down Expand Up @@ -63,8 +64,29 @@ This option shows all of the deallocations that were sampled. Keep in mind that

Some components inside of Gecko may implement their own memory management systems, and bypass the usage of system-level functions like `malloc` that are instrumented with this feature. For instance, some code could create a large buffer, and manage its own memory inside of that buffer. This feature would know about the allocation of the larger chunk of memory, but not how smaller allocations could be created inside of that buffer of memory. If this happens, information could be missing or misleading.

## JavaScript Allocations (experimental)
## JavaScript Allocations

There is also a JavaScript-only allocation feature. This may be less useful as it only samples the creation of JS objects, and does not track garbage collection or frees. In fact, the Native Allocations feature is a superset of the JavaScript allocations feature, and includes the JavaScript stack information. Enable this through the `Features` section of the popup.

![A screenshot of the call tree showing JS.](images/allocation-js.png)

## Valgrind's "Dynamic Heap Analysis Tool" DHAT

When working outside of Firefox, you can use [Valgrind's DHAT tool](https://valgrind.org/docs/manual/dh-manual.html). DHAT has its own viewer, but it lacks some of the visualization and filtering capabilities of the Firefox Profiler. The converted profile will lack some of the finer details like read, write, and access information, but it does contain the amount of bytes allocated. On a Linux system (or even a Linux docker image), you can install it via:

```sh
sudo apt-get install valgrind
```

Then run your command:

```
valgrind --tool=dhat ./my-program
```

A dhat profile will be output in the same directory as your program: `dhat.out.<pid>`. Drag that file into the profiler to view it. There will be 4 tracks containing the memory information. Only the call tree and flame graph are supported.

* **Bytes at End** - Allocations that were never freed when the program ended.
* **Bytes at Global Max** - Bytes allocated when the global heap size peaked.
* **Maximum Bytes** - The maximum bytes allocated at that call site at one time.
* **Total Bytes** - The total bytes allocated over the course of the program.

0 comments on commit b03e0f4

Please sign in to comment.