Diagnosing memory problems in your webpages

Use the Memory tool to diagnose memory issues that can impact the speed and stability of webpages.

Memory matters

If your webpage is performing well when it first loads, but gradually slows and sometimes crashes, the page's memory use might be the problem. The Memory tool is new to F12 developer tools in Internet Explorer 11.

To quickly see how much memory your webpage is using, open the new Performance dashboard from IE11's Tools menu or use CTRL + SHIFT + U. Click the memory use number to see a moving graph of memory use. To get back to the dashboard, click the graph.

When you want to know why you're seeing the numbers the Performance dashboard is showing, you need the Memory tool. It inspects your webpage's memory use and memory growth in detail, and identifies ways to improve.

Diagnosing a memory issue

After you've loaded your webpage in the browser, open the F12 tools and open the Memory tool (use the camera icon or CTRL + 7). You can start profiling from this screen and take heap snapshots during the profiling session.

If your problem is high memory usage from the start, but not memory growth, take one snapshot and examine it to find your bigger areas of memory use. If your memory use grows over time, you can compare snapshots to look at the areas where memory is growing.

The Summary View

After you've started profiling and taken some snapshots, you'll see a summary of the session that looks similar to this:

When you begin recording a session, the Total memory timeline shows the memory use by the current browser tab's processes as a graph over time.

You can add custom User marks to the timeline using the performance.mark() method in your JavaScript, with a label for the mark as the argument. You can add specific events this way. The label is displayed as a tool tip when the mouse pointer is hovered over the mark on the timeline.

Below the timeline, you'll see summaries of the heap snapshots.

What the snapshots summaries tell you

Each snapshot shows a thumbnail of the webpage as it appeared at the time the snapshot was taken and specifics about the memory usage of your code. After the first snapshot, subsequent snapshots add a summary of changes in memory use and object count.

In the second snapshot and later, the number of new objects created and old objects removed are shown below the object count. If these numbers are high, you might have a performance problem. When the amount of memory you use isn't bad, but a lot of objects are being created and removed, you create work for the garbage collector process which frees up memory. Garbage collecting uses processing power, so it's best to find ways to reuse or recycle these objects and give the garbage collector a break.

Tip  To see how much work the garbage collector is doing, profile your webpage with the UI Responsiveness tool.

 

If you click the memory usage numbers, you see a detailed view of that snapshot. If you click the memory change numbers, you see a comparison view highlighting the objects that have been added or modified. In the image above, Snapshot #2 includes a more info icon (a circle with an "i" in it) and the number 30 next to it. This number represents objects the Memory tool has identified as potential memory issues.

Something to look for

Another important factor to keep in mind is the difference between the number of objects being added and objects being removed. This is displayed in your second snapshot and beyond in the upper right in a "+x/-y" format.

In the set of snapshots above, it shows that each time we ran the process we suspected of having a memory issue, we increased the number of objects by 90, but only removed 9. This is a strong clue that there's a memory leak in the process. Memory leaks will keep expanding the memory use of your webpage during a user's session with it, causing slowness or even instability if the memory use grows too big.

The snapshot details view

Click one of the measurement numbers on a snapshot to see details of that measurement. The image below shows the view when you click on the memory issues number in a snapshot.

In the view above, you see the Dominators view of the snapshot's details, sorted so the issues are displayed first.

If you hover over the more info icon, you'll see a tooltip indicating why this item is a potential issue. In the example above, the DOM node is not attached to the DOM. This can happen when the node has been removed from the DOM, but is referred to elsewhere.

If you click the object, you'll see the objects referring to it in the bottom portion of the screen. In this case, an array called nodeholder contains a reference that is keeping the node in memory. If this is not what you expected, you can investigate further.

The three view types

  • Dominators view breaks out all individual HTML elements, DOM nodes, and JavaScript objects your code creates. This is the most detailed of the views.
  • Types view groups objects by their constructor function and gives a count of each type. This makes it easier to know how many arrays you have, how many strings, and so on. Those groups can be expanded to view individual objects.
  • Roots view shows the major root objects that you can expand to see the child objects associated with them.

In all three views, there are column headings for an object's size and retained size. The Size column documents the amount of memory the object itself uses. The Retained size column documents the amount of memory used by the object and its child nodes. For example, an HTMLDivElement might only consume tens of bytes itself, but might have a retained size in the megabytes because a large image or video is one of its child elements.

In large, complex pages, only the first two thousand objects are loaded, sorted by their retained size. In that case a filtering option is provided to help you narrow down the object set.

Additional options

You can change settings for the detailed display using a drop-down menu in the upper right of the Snapshot details.

  • Show built-ins shows internal objects created for a webpage by the browser that weren't created by the page itself. We don't show these by default, so you don't get distracted from your own code. However, sometimes it's helpful to see.
  • Display object IDs helps identify objects that have more than one reference. For example, the jQuery object often uses both jQuery and $ as references. Both references are shown with the same amount of memory usage, but they're using the same memory and the same object ID. Using object IDs can help separate unique objects from objects with multiple references.
  • Display circular references: (this option is removed in Cumulative Security Update for Internet Explorer (KB2976627)) In its simplest form, a circular reference happens when one object refers to another object that refers back to it, creating a loop. In more complex forms, the circular reference path can go through many objects. To make it easier to find the root of an object, circular references aren't shown. If you need to trace the paths of circular references, use this option to show them:
    • When circular references are displayed, you can find yourself examining the same object over and over if you're not careful. Turning on Display object IDs helps avoid that confusion.

Cumulative Security Update for Internet Explorer (KB2976627) introduces automatic filtering of circular references, indicating where they occur and trimming them. This makes it easier to dig deeper into object roots without getting lost in circular paths.

New in Windows 8.1 Update, when the object representing a function is displayed in the Memory tool, it is linked to its location in the source code and the color is changed to blue. Clicking on the function name or clicking its line and pressing ENTER switches you to the Debugger and focuses on that function's location in the corresponding script.

Note   The Memory tool displays function names as they exist in memory. If you're using JavaScript that's been compressed or compiled from another language, and you have a source map, you could click on a function named t in the Memory tool, but find the Debugger tool focused on a function named setOrigination. If this happens and it bothers you, try toggling off source map support for that file in the Debugger.

 

The comparison view

In snapshots where a change in memory use or object count is shown, click the amount of the change to see a comparison between that snapshot and the snapshot before it.

The comparison view works like the snapshot details view, except for three differences:

  • You can sort the Operation column based on which elements have changed and how they've changed.
  • The rows are color coded to represent their changes:
    • Blue: objects that exist in both snapshots, but were changed between the two.
    • Green: objects that were added between snapshots.
    • Black: no change.
  • Columns showing the difference in Size and Retained size are added.

In Windows 8.1 Update, the Operation column and color coding are removed, and the Scope menu is added. Scope shows you different views of the comparison and is particularly useful when combined with a three-snapshot method for memory analysis.

Cumulative Security Update for Internet Explorer (KB2976627) introduces dominator folding. This simplifies the contents of a snapshot by removing objects from the top-level views when they're logically parts of another object (such as a <BR> inside a <DIV> or a Scope being preserved by a Function). This reduces clutter and makes it easier to see the important items.

For example, the image below shows before and after views, demonstrating how dominator folding improves the "story" the tool is telling. The folded view (bottom) shows 30 HTML <DIV> elements which account for 15.64 MB or memory and are holding on to detached DOM nodes. Quite often it isn't important to know the composition of an object as mhch as simply knowing that it is too large and it is leaking (especially when using third-party libraries).

The three-snapshot method works as follows:

  • Load the page and use it normally for a few minutes.
  • Begin recording the session and take the first snapshot as a baseline.
  • Go through the scenario you think is causing a memory problem. Take the second snapshot.
  • Go through the scenario again. Take the third snapshot and then stop recording.

Click the numbers representing the increase in memory use or increase/removal of objects on Snapshot #3 to see its comparison with Snapshot #2. In that comparison view, the Scope menu gives you three choices:

  • Objects left over from Snapshot #2.
  • Objects added between Snapshot #2 and #3.
  • All objects in Snapshot #3.

When you compare Snapshot #1 to Snapshot #2, the Objects left over from Snapshot #1 option will include all the objects in the page that were there in the baseline. Most of those are elements used to build the page and just create clutter. They're always part of the webpage's memory use, not sources of the increase in memory use.

When you compare Snapshot #2 to Snapshot #3, the Objects left over from Snapshot #2 option identifies only the objects added in Snapshot #2 and still exist in Snapshot #3. Now you see the objects that were not only added after the baseline, but which persist after running the scenario a second time. These objects are worth inspecting more closely as you search for the source of your webpage's memory use problem.

Loading and saving sessions

You shouldn't have to reproduce your test case every time you want to analyze the data it produced. Added with Cumulative Security Update for Internet Explorer (KB2976627), the import (folder) and export (disk) icons on the tool's icon bar let you save memory profiling sessions for later inspection.

ECMAScript 6 containers

Windows 8.1 Update introduces support for Set, Map, and WeakMap container objects in the Memory tool, making it easier to inspect the details of their memory use. This support is only available when IE11 has not been switched down to a lower browser mode.

Understanding and Solving Internet Explorer Leak Patterns

Using the F12 developer tools

F12 updates in kb2976627