Memory terminology

Meggin Kearney
Meggin Kearney

This section describes common terms used in memory analysis, and is applicable to a variety ofmemory profiling tools for different languages.

The terms and notions described here refer to theChrome DevTools Heap Profiler. If you haveever worked with either the Java, .NET, or some other memory profiler, then this may be a refresher.

Object sizes

Think of memory as a graph with primitive types (like numbers and strings) and objects (associativearrays). It might visually be represented as a graph with a number of interconnected points asfollows:

Visual representation of memory.

An object can hold memory in two ways:

  • Directly by the object itself.
  • Implicitly by holding references to other objects, and therefore preventing those objects frombeing automatically disposed by a garbage collector (GC for short).

When working with the Heap Profiler in DevTools (a tool for investigating memory issues found in theMemory panel), you will likely find yourself looking at a few different columns of information. Twothat stand out areShallow Size andRetained Size, but what do these represent?

Shallow and Retained Size columns in Memory panel.

Shallow size

This is the size of memory that is held by the object itself.

Typical JavaScript objects have some memory reserved for their description and for storing immediatevalues. Usually, only arrays and strings can have a significant shallow size. However, strings andexternal arrays often have their main storage in renderer memory, exposing only a small wrapperobject on the JavaScript heap.

Renderer memory is all memory of the process where an inspected page is rendered: native memory + JSheap memory of the page + JS heap memory of all dedicated workers started by the page. Nevertheless,even a small object can hold a large amount of memory indirectly, by preventing other objects frombeing disposed of by the automatic garbage collection process.

Retained size

This is the size of memory that is freed once the object itself is deleted along with its dependentobjects that were made unreachable fromGC roots.

GC roots are made up ofhandles that are created (either local or global) when making areference from native code to a JavaScript object outside of V8. All such handles can be foundwithin a heap snapshot underGC roots >Handle scope andGC roots >Global handles.Describing the handles in this documentation without diving into details of the browserimplementation may be confusing. Both GC roots and the handles are not something you need to worryabout.

There are lots of internal GC roots most of which are not interesting for the users. From theapplications standpoint there are following kinds of roots:

  • Window global object (in each iframe). There is a distance field in the heap snapshots which isthe number of property references on the shortest retaining path from the window.
  • Document DOM tree consisting of all native DOM nodes reachable by traversing the document. Not allof them may have JS wrappers but if they have the wrappers will be alive while the document isalive.
  • Sometimes objects may be retained by debugger context and DevTools console (e.g. after consoleevaluation). Create heap snapshots with clear console and no active breakpoints in the debugger.

The memory graph starts with a root, which may be thewindow object of the browser or theGlobalobject of a Node.js module. You don't control how this root object is GC'd.

Root object can't be controlled.

Whatever is not reachable from the root gets GC.

Note: Both the Shallow and Retained size columns represent data in bytes.

Objects retaining tree

The heap is a network of interconnected objects. In the mathematical world, this structure is calledagraph or memory graph. A graph is constructed fromnodes connected by means ofedges, bothof which are given labels.

  • Nodes (or objects) are labelled using the name of theconstructor function that was usedto build them.
  • Edges are labelled using the names ofproperties.

Learnhow to record a profile using the Heap Profiler. Some of the eye-catching things we cansee in the following Heap Profiler recording include distance: the distance from the GC root. If almostall the objects of the same type are at the same distance, and a few are at a bigger distance,that's something worth investigating.

Distance from root example.

Dominators

Dominator objects are comprised of a tree structure because each object has exactly one immediate dominator. Adominator of an object may lack direct references to an object it dominates; that is, thedominator's tree is not a spanning tree of the graph.

In the following diagram:

  • Node 1 dominates node 2
  • Node 2 dominates nodes 3, 4 and 6
  • Node 3 dominates node 5
  • Node 5 dominates node 8
  • Node 6 dominates node 7

Dominator tree structure.

In the following example, nodes#7,#3, and GC are dominators of#10because they exist in every path from the root (GC) to#10. Specifically,#7is the immediate dominator of#10 as it's the closest dominator on the pathfrom GC to#10.

Animated dominator illustration.

V8 specifics

When profiling memory, it is helpful to understand why heap snapshots look a certain way. Thissection describes some memory-related topics specifically corresponding to theV8 JavaScriptvirtual machine (V8 VM or VM).

JavaScript object representation

There are three primitive types:

  • Numbers (e.g., 3.14159..)
  • Booleans (true or false)
  • Strings (e.g., 'Werner Heisenberg')

They cannot reference other values and are always leafs or terminating nodes.

Numbers can be stored as either:

  • an immediate 31-bit integer values calledsmall integers (SMIs), or
  • heap objects, referred to asheap numbers. Heap numbers are used for storing values that donot fit into the SMI form, such asdoubles, or when a value needs to beboxed, such as settingproperties on it.

Strings can be stored in either:

  • theVM heap, or
  • externally in therenderer's memory. Awrapper object is created and used for accessingexternal storage where, for example, script sources and other content that is received from theWeb is stored, rather than copied onto the VM heap.

Memory for new JavaScript objects is allocated from a dedicated JavaScript heap (orVM heap).These objects are managed by V8's garbage collector and therefore, will stay alive as long as thereis at least one strong reference to them.

Native objects are everything else which is not in the JavaScript heap. Native object, incontrast to heap object, is not managed by the V8 garbage collector throughout its lifetime, and canonly be accessed from JavaScript using its JavaScript wrapper object.

Cons string is an object that consists of pairs of strings stored then joined, and is a resultof concatenation. The joining of thecons string contents occurs only as needed. An example wouldbe when a substring of a joined string needs to be constructed.

For example, if you concatenatea andb, you get a string (a, b) which represents the resultof concatenation. If you later concatenatedd with that result, you get another cons string ((a,b), d).

Arrays - An Array is an Object with numeric keys. They are used extensively in the V8 VM forstoring large amounts of data. Sets of key-value pairs used like dictionaries are backed up byarrays.

A typical JavaScript object can be one of two array types used for storing:

  • named properties, and
  • numeric elements

In cases where there is a very small number of properties, they can be stored internally in theJavaScript object itself.

Map-an object that describes the kind of object and its layout. For example, maps are used todescribe implicit object hierarchies forfast property access.

Object groups

Each native objects group is made up of objects that hold mutual references to each other. Consider,for example, a DOM subtree where every node has a link to its parent and links to the next child andnext sibling, thus forming a connected graph. Note that native objects are not represented in theJavaScript heap—that's why they have zero size. Instead, wrapper objects are created.

Each wrapper object holds a reference to the corresponding native object, for redirecting commandsto it. In its own turn, an object group holds wrapper objects. However, this doesn't create anuncollectable cycle, as GC is smart enough to release object groups whose wrappers are no longerreferenced. But forgetting to release a single wrapper will hold the whole group and associatedwrappers.

Except as otherwise noted, the content of this page is licensed under theCreative Commons Attribution 4.0 License, and code samples are licensed under theApache 2.0 License. For details, see theGoogle Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.

Last updated 2024-12-05 UTC.