Skip to main content

Someone wanted to learn this too, so Grasp built them a personal learning path.

You can keep exploring this one or create your own

Shallow vs. Retained Size: Understanding Memory Impact

Hello! Welcome to the final module of our course, "Memory Leak Detection and Analysis."

In the previous modules, we've honed your skills in debugging code execution, analyzing performance bottlenecks, and diagnosing network issues. We now turn to the fourth critical pillar of web application health: memory management. While JavaScript's automatic garbage collection handles many memory tasks, it doesn't prevent all problems. Memory leaks can silently degrade performance over time, leading to sluggishness, unresponsiveness, and even browser crashes.

This lesson kicks off our exploration of the Memory panel. Our goal is to differentiate between Shallow Size and Retained Size to accurately assess the memory impact of objects. Mastering these two fundamental metrics is the first and most crucial step toward identifying and fixing memory leaks in your applications.

Why We Analyze Memory in JavaScript

JavaScript engines use a process called Garbage Collection (GC) to automatically reclaim memory that is no longer in use. In theory, this means you don't have to worry about memory allocation and de-allocation. In practice, it's easy to accidentally create situations where references to objects are kept alive longer than necessary, preventing the GC from cleaning them up. This is a memory leak.

To set the stage, let's watch a brief introduction to common causes of memory leaks and the tools Chrome DevTools provides to analyze them.

Plugging Memory Leaks With The Chrome Dev Tools - Ben Dilts

This video provides a great overview of why memory leaks happen in JavaScript and introduces the memory analysis tools in DevTools.

Please watch from 03:03 to 07:37. The speaker, Ben Dilts, covers the basics of garbage collection and lists several common ways memory can be unintentionally retained, such as through event listeners or even console.log statements.

As the video explained, the primary tool for this kind of investigation is the Heap Snapshot, which gives us a detailed view of all the objects in memory at a specific moment. When you take a heap snapshot, two of the most important columns you'll see are "Shallow Size" and "Retained Size." Let's define them.

Shallow Size vs. Retained Size

At first glance, these terms might seem similar, but they tell you very different things about an object's memory footprint.

The difference between Shallow Size and Retained Size

This article provides excellent, clear definitions for both Shallow and Retained Size, along with a simple example that makes the difference very concrete.

Please read the entire article. It's short and to the point. Focus on the definitions of Shallow and Retained Size and how the example with Objects A, B, and C illustrates the calculation for Retained Size.

Let's consolidate what you've just read.

Chrome DevTools Memory Tab: Shallow Size vs. Retained Size
The Heap Snapshot view in the DevTools Memory panel. The key metrics, Shallow Size and Retained Size, are highlighted.

Shallow Size

  • Definition: The shallow size is the memory that is held by the object itself.
  • Analogy: Think of an array object. Its shallow size includes the memory for the array's own properties (like length) and the memory for the list of references to its elements. It does not include the size of the objects that the references point to.
  • Usefulness: Shallow size is useful for identifying objects that are intrinsically large, such as a very long string or a large buffer. However, it doesn't give you the full picture of an object's memory impact.

Retained Size

  • Definition: The retained size is the total amount of memory that will be freed by the garbage collector once this object is deleted. It is the shallow size of the object itself plus the shallow sizes of all other objects that are kept alive only because of this object.
  • Analogy: Imagine a DOM element that is the root of a large component subtree. If you remove this root element and it's the only thing holding references to its children, the entire subtree can be garbage collected. The retained size of that root element would be its own size plus the size of all its descendant nodes and their associated JavaScript objects.
  • Usefulness: This is the most important metric for hunting memory leaks. An object might have a tiny shallow size but a massive retained size. This indicates it's acting as a "gatekeeper," preventing a large graph of other objects from being garbage collected. When you look for leaks, you almost always start by sorting by Retained Size.

The video you watched earlier has a great segment where the speaker does exactly this.

Plugging Memory Leaks With The Chrome Dev Tools - Ben Dilts

Let's see this concept in action. The speaker demonstrates how sorting by Retained Size immediately brings the most significant memory consumers to the top.

Watch from 10:41 to 13:05. Notice how the speaker sorts the heap snapshot by 'Retained Size' to find the 'big stuff' and begins investigating the objects that are holding onto the most memory.

This practical workflow—taking a snapshot and immediately sorting by Retained Size—is the standard first step in almost any memory investigation.

Test your understanding!

Let's consider a scenario with three objects in memory:

  • userProfile (Shallow Size: 1 KB). It holds a reference to a largeDataSet object.
  • dataCache (Shallow Size: 2 KB). It also holds a reference to the same largeDataSet object.
  • largeDataSet (Shallow Size: 500 KB).
  1. What is the Retained Size of the userProfile object?
  2. Now, imagine the dataCache is cleared, and its reference to largeDataSet is removed. What is the new Retained Size of the userProfile object?
Show answer
  1. The Retained Size of userProfile is 1 KB. Although it references largeDataSet, it doesn't uniquely retain it. The dataCache object also keeps largeDataSet alive. Therefore, deleting userProfile would not free the memory used by largeDataSet.

  2. After the dataCache reference is removed, the Retained Size of userProfile becomes 501 KB (1 KB for userProfile itself + 500 KB for largeDataSet). Now, userProfile is the only object holding a reference to largeDataSet, so if userProfile were to be garbage collected, largeDataSet would be too.

Conclusion

In this lesson, we've established the foundational knowledge for memory profiling in Chrome DevTools. You now understand the critical difference between an object's immediate size and its overall impact on your application's memory usage.

Key Takeaways:

  • Shallow Size is the memory occupied by an object itself. It's useful for finding objects that are individually large.
  • Retained Size is the total memory that would be freed if an object were deleted, including all other objects it exclusively keeps alive.
  • For finding memory leaks, Retained Size is the key metric. Sorting a heap snapshot by Retained Size is the best way to start an investigation, as it points you to the objects that are preventing large chunks of memory from being garbage collected.

You now have the vocabulary to interpret the main view of a heap snapshot. In our next lesson, we will build directly on this by learning how to use heap snapshots to identify memory leaks, such as detached DOM nodes, by comparing snapshots taken at different times. This powerful technique allows you to see exactly what memory is being leaked between user actions.

Can't find a good explanation? Sign up and we'll make it for you

Sign up