Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file not shown.
Binary file not shown.
Binary file not shown.
Comment thread
mikehoffms marked this conversation as resolved.
Comment thread
mikehoffms marked this conversation as resolved.
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ ms.author: msedgedevrel
ms.topic: conceptual
ms.service: microsoft-edge
ms.subservice: devtools
ms.date: 01/30/2024
ms.date: 09/16/2024
---
<!-- Copyright Meggin Kearney

Expand Down Expand Up @@ -102,12 +102,22 @@ To switch between views, use the dropdown list at the top of the **Memory** tool

![Switch views selector](./heap-snapshots-images/heap-snapshots-view-dropdown.png)

> [!NOTE]
> Not all properties are stored on the JavaScript heap. Properties implemented using getters that run native code aren't captured. Also, non-string values such as numbers aren't captured.

<!-- ------------------------------ -->
#### Items omitted from heap snapshots

Properties that are implemented using getters that run native code aren't captured in the heap snapshot, because such properties are not stored on the JavaScript heap.

Non-string values, such as numbers, aren't captured.


<!-- ------------------------------ -->
#### Summary view

The **Summary** view in the **Memory** tool lists:
* Object constructor groups.
* Special category names, such as **(array)**, **(compiled code)**, or a list of properties such as **{foo, bar, baz}**.

Initially, a heap snapshot opens in the **Summary** view, which displays a list of constructors:

![Summary view](./heap-snapshots-images/heap-snapshots-constructor-retainers.png)
Expand All @@ -124,31 +134,37 @@ For each constructor in the list, the **Summary** view also shows a number such

After expanding a constructor in the **Summary** view, all of the constructor's instances are displayed. For each instance, the shallow and retained sizes are displayed in the corresponding columns. The number after the `@` character is the unique ID of the object, allowing you to compare heap snapshots on per-object basis.

###### Constructor entries in the Summary view

<!-- ---------- -->
###### Constructor entries

The **Summary** view in the **Memory** tool lists object constructor groups:

![Constructor groups](./heap-snapshots-images/heap-snapshots-constructor-highlight.png)

The constructor groups in the **Summary** view might be built-in functions such as `Array` or `Object` or they might be functions defined in your own code.
The constructor groups in the **Summary** view might be built-in functions such as `Array` or `Object`, or they might be functions that are defined in your own code.

To reveal the list of objects that were instantiated by a given constructor, expand the constructor group.

###### Special category names in the Summary view

The **Summary** view also contains special category names that aren't based on constructors. These special categories are:
<!-- ---------- -->
###### Special category names

<!-- from https://github.com/sethbrenith/sethbrenith.github.io/blob/main/heap-snapshot-names.md -->

The **Summary** view in the **Memory** tool includes the following special category names, which aren't based on constructors. Most of these category names are displayed in parentheses.

| Category name | Description |
|:--- |:--- |
| **(array)** | Various internal array-like objects that don't directly correspond to objects visible from JavaScript, such as the contents of JavaScript arrays, or the named properties of JavaScript objects. |
| **(compiled code)** | Internal data that V8 (Microsoft Edge's JavaScript engine) needs to run functions defined by JavaScript or WebAssembly. V8 automatically manages memory usage in this category: if a function runs many times, V8 uses more memory for that function so that the function runs faster. If a function hasn't run in a while, V8 might delete the internal data for that function. |
| **(concatenated string)** | When two strings are concatenated together, such as when using the JavaScript `+` operator, V8 might choose to represent the result internally as a _concatenated string_. Rather than copying all of the characters of the two strings into a new string, V8 creates a small object which points to the two strings. |
| **InternalNode** | Objects allocated outside of V8, such as C++ objects defined by Blink, Microsoft Edge's rendering engine. |
| **(object shape)** | Information about objects, such as the number of properties they have and a reference to their prototypes, which V8 maintains internally when objects are created and updated. This allows V8 to efficiently represent objects with the same properties. |
| **(sliced string)** | When creating a substring, such as when using the JavaScript `substring` method, V8 might choose to create a _sliced string_ object rather than copying all of the relevant characters from the original string. This new object contains a pointer to the original string and describes which range of characters from the original string to use. |
| **system / Context** | Local variables from a JavaScript scope which can be accessed by some nested function. Every function instance contains an internal pointer to the context in which it executes, so that it can access those variables. |
| **(system)** | Various internal objects that haven't yet been categorized in any more meaningful way. |
| **{foo, bar, baz}** | Plain JavaScript objects categorized by interface (property list), in curly braces. Plain JavaScript objects are not listed in a category named **Object**, but are instead represented by names and categories that are based on the properties that the object contains, such as **{foo, bar, baz}**. |
| **InternalNode** | Objects allocated outside of V8, such as C++ objects defined by Blink, Microsoft Edge's rendering engine. |
| **system / Context** | Local variables from a JavaScript scope which can be accessed by some nested function. Every function instance contains an internal pointer to the context in which it executes, so that it can access those variables. |


<!-- ------------------------------ -->
Expand Down Expand Up @@ -204,6 +220,8 @@ In the following screenshot, a string object was selected in the **Summary** vie

![The Retainers section](./heap-snapshots-images/retainers-section.png)


<!-- ---------- -->
###### Hide cycles

In the **Retainers** section, when you analyze the objects which retain the selected object, you might encounter _cycles_. Cycles occur when the same object appears more than once in the retainer path of the selected object. In the **Retainers** section, a cycled object is indicated by being grayed out.
Expand All @@ -212,33 +230,15 @@ To help simplify the retainer path, hide cycles in the **Retainers** section by

![The Filter edges dropdown menu in the Retainers section, 'Hide cycled' is selected](./heap-snapshots-images/filters-retainers-memory-tool-no-hide-cycled.png)


<!-- ---------- -->
###### Hide internal nodes

_Internal nodes_ are objects that are specific to V8 (the JavaScript engine in Microsoft Edge).

To hide internal nodes from the **Retainers** section, in the **Filter edges** dropdown menu, select **Hide internal**.


<!-- ====================================================================== -->
## Configure the Shallow Size column to include an entire object's size

By default, the **Shallow Size** column in the **Memory** tool only includes the size of the object itself. The _shallow size_ is the size of the JavaScript heap that's _directly_ held by an object. The shallow size of an object is usually small, because a JavaScript object often only stores its description of the object, not the values, in the object's directly held memory. Most JavaScript objects store their values in a _backing store_ that's elsewhere in the JavaScript heap, and only expose a small wrapper object on the portion of the JavaScript heap that's directly owned by the object. For example, JavaScript `Array` instances store the contents of the array in a backing store, which is a separate memory location that's not included in the array's shallow size.

You can configure the **Shallow Size** column to report the entire size of objects, including the size of the object's backing store.

To include the entire size of objects in the **Shallow Size** column:

1. In DevTools, click the **Customize and control DevTools** (![Customize and control DevTools icon](./heap-snapshots-images/customize-icon.png)) button, and then click **Settings** (![Settings icon](./heap-snapshots-images/settings-icon.png)). Or, while DevTools has focus, press **F1**.

1. In the **Experiments** section, select the checkbox **In heap snapshots, treat backing store size as part of the containing object**.

1. Click the **Close** (x) button of the **Settings** page, and then click the **Reload DevTools** button.

1. Take a new heap snapshot. The **Shallow Size** column now includes the entire size of objects:

![The Shallow Size column of a heap snapshot](./heap-snapshots-images/shallow-size-entire-object.png)


<!-- ====================================================================== -->
## Filter heap snapshots by node types

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,30 +85,33 @@ Nodes that aren't reachable from the root can get garbage-collected.
<!-- ====================================================================== -->
## Object sizes and distances

When working with the **Memory** tool, you will likely find yourself looking at the following columns of information:
The **Memory** tool displays the following columns of information:

* **Distance**
* **Shallow Size**
* **Retained Size**
* The **Distance** column
* The **Shallow size** column
* The **Retained size** column

![The Distance, Shallow Size, and Retained Size columns in the Memory tool](./memory-101-images/shallow-retained.png)

The numbers in the **Shallow Size** and **Retained Size** columns are the number of bytes.
These columns are described below.


<!-- ------------------------------ -->
#### Distance

The _distance_ of an object in the JavaScript heap is the number of nodes on the shortest path between the object and the GC root. The shorter the distance, the more likely it is that this object plays an important role in the memory usage of the webpage.
The _distance_ of an object in the JavaScript heap is the number of nodes on the shortest path between the object and the GC root. The shorter the distance, the more likely it is that this object plays an important role in the memory usage of the webpage.


<!-- ------------------------------ -->
#### Shallow size

The _shallow size_ is the size of the JavaScript heap that's _directly_ held by an object. The shallow size of an object is usually small, because a JavaScript object often only stores its description of the object, not the values, in the object's directly held memory. Most JavaScript objects store their values in a _backing store_ that's elsewhere in the JavaScript heap, and only expose a small wrapper object on the portion of the JavaScript heap that's directly owned by the object.

The **Memory** tool can be configured to report the total memory size of objects instead of only the memory size they directly hold. To learn more, see [Configure the Shallow Size column to include an entire object's size](./heap-snapshots.md#configure-the-shallow-size-column-to-include-an-entire-objects-size) in _Record heap snapshots using the Memory tool_.

Nevertheless, even a small object can hold a large amount of memory _indirectly_, by preventing other objects from being disposed of by the garbage collection process.

The numbers in the **Shallow size** column are the number of bytes.


<!-- ------------------------------ -->
#### Retained size

Expand All @@ -120,6 +123,8 @@ The retained size can't be smaller than the shallow size.

When an object is retained by multiple nodes, the object's size appears in the retained size of the retainer node that has the shortest path to the GC root.

The numbers in the **Retained size** column are the number of bytes.


<!-- ====================================================================== -->
## Retainers
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ In Microsoft Edge 103, when taking a heap snapshot in the **Memory** tool, there
For history, see [Issue 12769: Improve categorization of objects in heap snapshots](https://bugs.chromium.org/p/v8/issues/detail?id=12769).

See also:
* [Constructor entries in the Summary view](../../../memory-problems/heap-snapshots.md#constructor-entries-in-the-summary-view) in _Record heap snapshots using the Memory tool_.
* [Constructor entries](../../../memory-problems/heap-snapshots.md#constructor-entries) in _Record heap snapshots using the Memory tool_.


<!-- ====================================================================== -->
Expand Down