May 26, 2021 Chrome A guide to developing tools
2. You should ask yourself some questions
3. Terminology and fundamentals
4. Prerequisites and some useful tips
Memory leakage refers to the gradual loss of computer memory. M emory leaks occur when a program is always unable to free up memory. JavaScript web applications may often experience problems such as memory leaks in local programs, such as leaks and bloating, but JavaScript has a memory recycling mechanism to address such problems.
Although JavaScript uses memory recyclers to automatically manage memory, an efficient memory management strategy is still important. I n this chapter, we'll detail memory issues in JavaScript web applications. Try these examples as you learn some features, which can improve your understanding of how tools work.
Before you begin, check out the Memory 101 page to familiarize yourself with the terminology.
Note: Some of the features we use later are supported only by Chrome Canary. We recommend using this version of the tool so that you can perform optimal memory analysis on your application.
Typically, when you think your program has a memory leak, you need to ask yourself three questions:
View content
This section describes the terms commonly found in memory analysis, which are useful even in memory analysis tools in other languages. The terms and concepts described here are used in the heap profiler interface and in the corresponding documentation.
By understanding these terms, you can use the tool more efficiently. If you've ever used Java, .Net, or other memory analyzers, the content of this article is a boost for you.
Think of the memory condition as a picture with some basic types (such as numbers and strings) and objects (associated arrays). If you represent the contents of the diagram with some interconnected points like the following, it may help you understand this:
Objects can get memory in two ways:
When you use the heap analyzer in DevTools, a tool for finding memory problems under Profiles, you'll find that you're seeing several columns of information. The most important of these are The Number Size and Retained Size, but what exactly do these two columns mean?
This refers to the amount of memory that the object itself gets.
A typical JavaScript object gets some reserved memory for their description and for storing instantly generated values. T ypically, only arrays and strings have a relatively significant shallow size. However, strings and external arrays tend to have their own primary memory in render memory, exposing only a few wrapped objects to the JavaScript heap.
Rendering memory refers to the memory used during the rendering of the monitored page: the originally allocated memory, the memory of the page in the JS heap, and the memory overhead of all other objects in the JS heap as a result of the page. However, even a small object can indirectly keep a large amount of memory by preventing the garbage collector from automatically reclaiming other objects.
This refers to the amount of memory released when an object and its related objects are deleted together, and GC roots cannot reach it.
GC roots are made up of handles (local or global) that are created when references JavaScript objects outside of V8 of native code. T hese handles can be found in the GC roots and Handles and GC roots and Global handles in the re-heaped snapshots. W ithout talking about the details of the browser implementation, explaining the handle in this article can be confusing to the reader, so the details of the handle are not covered in this article. In fact, neither GC roots nor handles are something you need to worry about.
There are many internal GC roots, but users are not interested in most of them. From an application perspective, there are several roots:
Note: We recommend that readers take snapshots of the heap when the console is emptied and there are no active break points in the debugger.
The following memory starts with a root node, which may be the window object of the browser or the Global object .js node module. You don't need to know how this object is recycled.
Any elements that cannot be obtained by the root node will be recycled.
Tip: Both The Number and Retained size represent the data in bytes.
As we said earlier, heaps are networks of connected objects. I n the mathematical world, this structure is called a graph or memory diagram. A diagram is made up of nodes and edges, and nodes are connected by edges, where nodes and edges have corresponding labels.
Later in this article, you'll learn how to use a heap profiler to record information. I n the heap analyzer record, we can see several columns, including Distance: Distance refers to the distance from the root node to the current node. One situation worth exploring is that almost all objects of the same kind have the same distance, but distance for a small number of objects has a larger value than others.
The leader object is made up of a tree structure because each object has only one leader. The dominant user of an object does not necessarily refer directly to the object it dominates, that is, the dominant tree is not the building tree of the graph.
In the figure above:
In the following example, node #3 is the leader of #10, but #7 nodes are also on each simple path from GC to #10 nodes. Therefore, if object B exists on each simple path from the root node to object A, then object B is the leader of object A.
In this section, we're talking about memory for V8 JavaScript virtual machines (V8 VMs or VMs). These are useful for understanding why heap snapshots look like what you see above.
There are three main types of JavaScript:
These types are leaf or end nodes in the tree, and they cannot reference other values.
The number type can be stored like this:
Strings can be stored in:
The memory of the new JavaScript object is allocated by a specific JavaScript heap, or VM heap. These objects are managed by the V8 garbage collector and will not be recycled as long as there is a strong reference to them.
A local object is everything that is not stored in the JavaScript heap. In contrast to local objects and heap objects, their lifetimes are not managed by the V8 garbage collector and can only be used by JavaScript objects that encapsulate them.
Cons string is an object that holds a pair of strings, and the object stitches the strings together, with the end result being a string in series. S titched cons string content only appears when needed. A good example is that if you want to get a subs string of strings, you have to build with a function.
For example, if you series the a and b objects, you get a string (a,b) that represents the result of stitching. If you then add an object d, you will live another string ((a, b), d).
Array - An array is an object with a numeric key. T hey are widely used in V8 VMs to store large amounts of data. In a data structure such as a dictionary, a collection of key-value pairs is backed up with arrays.
A typical JavaScript object for storage can be one of two array types:
If you want to store a small number of properties, they can be stored directly in JavaScript objects.
Map - An object that describes the object and the kind of layout it lays. For example, maps are used to describe the implicit object structure of Fast Property Access.
Each local group of objects consists of objects that remain referenced to each other. T ake a DOM subshuil, where each node has a connection to the parent node and a link to the child node and the brother node, so that all nodes are connected to a single graph. I t is important to note that local objects do not appear in the JavaScript heap, so their size is 0. Accordingly, a corresponding encapsulation object is created for each local object to be used.
Each encapsulated object contains a reference to the corresponding local object in order to be able to redirect commands to the local object. O bject groups, on the other hand, contain these encapsulated objects, but this does not create a dead loop that cannot be recycled because the garbage collector automatically releases encapsulation objects that are not referenced. But once you forget to release an encapsulation object, you may not be able to release the entire group and the associated encapsulation object.
Note: A good way to analyze memory problems in Chrome is to configure a clean-room testing environment.
If a page consumes a lot of memory, you can use the Chrome Task Manager memory bar to monitor the memory consumed by the page when performing activities that might consume a lot of memory.
If you want to use Task Manager, click menu and Tools or use the shortcut
Shift
plus
Esc
Once opened, right-click on the header of the column and enable the JavaScript memory column.
The first step in solving a problem is to have the ability to identify the problem first. T his means that it is ability to create a repeatability test for basic problem measurement. W ithout a re-usable program, you can't measure problems effectively. In addition, if you don't even have a test baseline, you won't know if the changes you've made have improved the performance of your program.
The timeline panel is very helpful in finding out when a problem occurs. W hen a page or application loads or interacts, it gives a complete overview of the time consumption of the entire process. All events, from loading resources to parsing JavaScript, compute styles, garbage collection, and redrawing, appear on the timeline.
When looking for memory problems, the Memory view of the timeline panel can be used to trace:
To learn more about finding problems that can cause memory leaks during memory analysis, check out Zack Grossbart's Memory profiling with The Chrome DevTools
The first thing to do is to find out what you think might cause a memory leak. This activity can be anything, like positioning on a site, mouse hover events, click events, or events that can have a negative impact on performance when interacting with a page.
In the timeline panel, start recording
Ctrl
plus
E
or
Cmd
plus
E
then execute the sequence of activities you want to test.
To force garbage collection, click
the garbage icon ( ) at the bottom.
In the following image, we can see that some nodes are not recycled, and the pattern corresponding to these nodes is the pattern pattern of memory leakage:
If you see a jagged pattern (at the top of the memory panel) after a few iterations, this means that you have allocated a large number of short-lived objects. However, if this sequence of operations does not preserve memory, or if the number of DOM nodes does not fall to the baseline at the beginning of execution, then you have good reason to suspect that a memory leak has occurred here.
Once you've identified the problem, you can use heap profiler in Profiles panel to find out where the problem came from.
Example: You can try this example to exercise how to use timeline memory mode efficiently.
The garbage collector (like V8) can locate objects where your program is alive and dead, or even ind accessible.
If the garbage collector (GC) fails to reclaim dead objects in your javaScript due to some logical error, the memory they consume will not be used again. Situations like this eventually slow down your application's execution over time.
This can eventually happen if you are writing code that is referenced by other code even variables and event listeners that are no longer needed. When these references exist, the garbage collector cannot clean up the objects correctly.
There will be some DOM element updates/deaths during the lifetime of your application, and don't forget to check out and eliminate variables that reference those elements. Examine the properties of objects that may reference other objects (or other DOM elements) and keep an eye out for variable caches that may grow over time.
In the configuration panel, select
Take Heap Snapshot,
then
tap Start
or use the
Cmd
or
Ctrl
shortcuts.
E
E
The initial snapshot is in render memory, and when you click the snapshot icon to view it, it is transferred to DevTools. When the snapshot is loaded into DevTools and parsed, a number appears below the snapshot title that represents the total size of all accessible JavaScript objects:
Example: Try using this example to monitor the use of timeline summary memory.
Click clear all configuration icons ( ) to clear the snapshot (both in DevTools and in render memory are deleted):
Note: Closing the DevTools window directly does not delete the profile in rendered memory. When the DevTools window is reopened, all previously generated snapshots appear in the snapshot list.
Remember, as mentioned in the previous article, you can force garbage collection from DevTools, and this can be part of your snapshot workflow. W hen a heap snapshot is generated, DevTools is automatically garbage collected. In the timeline, this process can be easily achieved by clicking the trash button ( ) .
Example: Try this example and use the heap analyzer for analysis. You should see the number of times the project has been allocated.
A snapshot can be viewed from a different perspective to better accommodate different needs. To switch between views, use the selector at the bottom of the view:
There are three default views:
The lead view can be enabled in the settings panel - the contents of the lead tree are displayed and can be used to find the gather point.
The properties and property values of the object belong to different types and have corresponding colors. Each property has one of four types:
An object named System does not have the appropriate JavaScript type. T hey are part of the object system for JavaScript virtual machines. V8 assigns most internal objects to the same heap as user JS objects, so these are just V8 internal content.
To find an object in the heap, you can
Ctrl
and enter the
ID of the object.
F
At first, the snapshot is opened in the summary view, showing the overall state of the object, and the view can be expanded to display instance information:
The top entrance is the "total" line, which shows:
When you want to expand the total line like the one above, all of its instances are displayed. F or each instance, its value size and retained size are shown in the appropriate columns. The number after the character is the ID of the object, which allows you to compare snapshots of the heap on top of each object.
Example: Use this page to learn how to use summary views.
Keep in mind that yellow objects indicate that JavaScript objects reference them, while red objects refer to detached nodes referenced from a yellow background node.
This view is used to compare different snapshots so that you can compare their differences to find objects that have memory leaks. To find out if a particular program caused a leak (for example, usually a relative two actions, like opening a document and then closing it without leaving memory garbage), you can try the following steps:
In the comparison view, the difference between the two snapshots is shown. When you expand a total portal, the added and deleted object instances are displayed:
Example: Try this example (open in a tab) to learn how to use comparison views to monitor memory leaks.
Containing a view is essentially a top view of the structure of your application object. It allows you to see inside function closures, and even observe the virtual machine internal objects that make up JavaScript objects, which lets you see how much memory your app uses at the bottom.
This view provides multiple access points:
Here are common examples of included views:
Example: Use this page (open in a new tab) to try to find closures and event processors in this view.
Naming a function helps you distinguish between different closures in a snapshot. For example, the following function is not named:
function createLargeClosure() {
var largeStr = new Array(1000000).join('x');
var lC = function() {
// this is NOT a named function
return largeStr;
};
return lC;
}
Here's the named function:
function createLargeClosure()
{
var largeStr = new Array(1000000).join('x');
var lC = function lC() {
// this IS a named function
return largeStr;
}; return lC;
}
Example: Try this example to analyze the memory impact of closure. You may be interested in the following example, which gives you insight into heap memory allocation
One of the features of the tool is its ability to display bidirectional dependencies between browser-local objects (DOM nodes, CSS rules) and JavaScript objects. This helps to discover invisible leaks caused by forgetting to detach doM sub-trees.
DOM leaks can be more than you think. Consider the following example - when will #tree be recycled?
var select = document.querySelector;
var treeRef = select("#tree");
var leafRef = select("#leaf");
var body = select("body");
body.removeChild(treeRef); //#tree can't be GC yet due to treeRef
treeRef = null; //#tree can't be GC yet due to indirect
//reference from leafRef
leafRef = null; //#NOW can be #tree GC
#leaf contains references to its father (parent node) and recursive to #tree, so the entire tree under #tree can only be recycled if leafRef fails.
Example: Try this example to help you understand where DOM nodes are prone to leaks and how to find them. You can also continue to try this later example doM leak Bin imagines more.
To learn more about DOM leaks and the basics of memory analysis, see Find and debugging memory leaks with the Chrome DevTools from Gonzalo Ruiz de Villa.
Summary and include views make it easier to find local objects - there are entry nodes for local objects in the view:
Example: Try this example (open in a new tab) to experience the detached DOM tree.
The dominant view shows the dominant tree of the heap diagram, which is a bit like an included view, but some properties are missing. This is because the leader object may lack a direct reference to it, that is, the dominant tree is not a build tree.
Note: In Chrome Canary, the dominant view can be enabled in Settings and Show advanced snapshots properties, and you can choose the dominant view after you restart your browser.
Example: Try this example (open in a new tab) to see if you can find the accumulation point. You can then try running the retainning paths and dominators.
The Object Tracker combines the details of snapshots in the Heap Analyzer with incremental updates to the timeline and tracking information. Similar to these tools, the allocation process for tracking the object heap involves starting a record, performing a series of operations, and stopping the recording and analysis.
The object analyzer periodically generates snapshots in the record (approximately every 50 milliseconds) and also generates a snapshot when the record finally stops. The heap allocation profile shows where the object was created and identifies the retention path.
Turn on and use the object tracker
To get started with object trackers:
The bar chart of the top bar indicates when the object was found in the heap. The height of each bar chart corresponds to the size of the most recently allocated object, and its color indicates whether the objects are still in the lifetime in the last snapshot: blue indicates that the object still exists at the end of the timeline, and gray indicates that the object is allocated within the timeline, but has been recycled by the garbage collector.
In the example above, an operation was performed 10 times. T his simple program loads five objects, so it shows five blue bar patterns. B ut the bar chart on the far left shows a potential problem. Next you can use the slider in the timeline to zoom in on this particular snapshot, and then look at the objects that have recently been assigned to this point.
Clicking on a specific object in the heap displays its retention tree at the top of the heap snapshot. Checking the object's retention path will let you understand why the object is not recycled, and you can make changes in your code to make an unwanted reference.
Q: I don't see all the properties of the object, I don't see those non-string values, why?
Not all properties are stored in the JavaScript heap. S ome of these are done by executing the geter of the local code. S uch properties are not captured in the heap snapshot because to avoid the consumption of calling the acquirer and to avoid changes in program declarations (when the acquirer is not a "pure" method). Similarly, non-string values, such as numbers, are not captured in order to reduce the size of the snapshot.
Q: What does the number after the character mean - is this an address or ID? Is the value of the ID unique?
This is the object ID. T he address of the display object is meaningless because the address of the object is offset during garbage collection. T hese object IDs are real IDs - that is, they exist in multiple snapshots that survive, and their values are unique. T his allows you to accurately compare the heap states of two different periods. Maintaining these IDs increases the overhead of the garbage collection cycle, but only after the first heap snapshot is generated - there is no overhead if the heap profile is not used.
Q: Will the "Dead" (inability to reach) object be included in the snapshot?
No, only reachable objects appear in the snapshot. Also, garbage collection always begins when a snapshot is taken.
Note: When writing code, we want to avoid this garbage collection method to reduce the change in the size of the heap that was already used when the heap snapshot was taken. This is still being implemented, but garbage collection is still performed outside of the snapshot.
Q: What is the composition of the GC root node?
Many things:
Q: The tutorial says use the heap analyzer and timeline memory view to find memory leaks. What tools should I use first?
Timeline, using this tool to detect excessive memory usage when you realize that the page is starting to slow down. Slowing down is a typical memory leak symptom, and of course it can be caused by other situations - maybe you have some pictures on your page or a network bottleneck, so make sure you fix the actual problem.
To diagnose whether memory is the cause of the problem, open the memory view of the timeline panel. C lick the record button and start interacting with the program, repeating what you think is wrong. S top recording, and the displayed picture represents the memory state assigned to the application. If the picture shows that the total amount of memory consumed has been growing (continues to be unseeded), there is a high probability of a memory leak.
A normal application, its memory state map should be a jagged graph, because memory allocation is reclaimed by the garbage collector. T here's no doubt about that - operations in JavaScript are always consumed, and even an empty requestAnimationFrame has a jagged pattern, which is inevitable. As long as you make sure there are no sharp graphics, it's like a lot of allocation, because that means a lot of garbage on the other side.
What you need to care about is the rate at which the steepness of this curve increases. I n the memory view, there are DOM node counters, document counters, and event listening counters, which are all useful in diagnostics. DoM nodes use native memory and do not directly affect JavaScript memory charts.
If you feel a memory leak in your program, the heap analyzer can help you find the source of the memory leak.
Q: I noticed that there are some DOM nodes in the heap snapshot, some of which are red and indicate that they are "separated DOM trees" while others are yellow, what does that mean?
You'll notice that these nodes have different colors, and the red nodes (with a darker background) don't have a direct reference to them by JavaScript, but are still in existence because they are part of a separate DOM tree. There may be nodes in the JavaScript-referenced tree (perhaps closures or variables) that just prevent the entire DOM tree from being recycled.
Yellow nodes (whose background is also yellow) are directly referenced by JavaScript objects. L ook for yellow nodes in the same detached DOM tree to lock references in JavaScript. Reaching related elements from the DOM window should be a chain of properties (for example, window.foo.bar the doM window.
Here's an animation of the position of the stand-alone node in the entire image:
Example: Try this example of a stand-alone node, where you can see how the node changes in the timeline, and you can generate a heap snapshot to find the stand-alone node.
Q: What does The Little and Retained Size mean? What's the difference between them?
In fact, objects stay in memory in two ways - by keeping them directly in memory (such as window and document objects) through other objects that are in lifetime, or implicitly in memory (like DOM objects) by retaining references to parts of local render memory. T he latter results in related objects not being automatically reclaimed by the memory recycler, resulting in a leak. The memory size contained in the object itself is the scale (generally the array and string have a relatively large scale).
If an object prevents other objects from being reclaimed, the memory it occupies will be huge, no matter how large the object is. The amount of memory that can be reclaimed when an object is deleted is called the amount of retention.
Q: There is a lot of data in the builder and in the reserved view. Where do I start if I find a leak?
In general, it's a good idea to start with the first object that's left in your tree, because the contents are sorted by distance (that is, the distance to window).
In general, the shortest distance among reserved objects is usually the one most likely to cause a memory leak.
Q: What are the differences between summary, comparison, dominance, and inclusion views?
Different views of the data can be selected at the bottom of the screen for different purposes.
Q: What do the different builder portals in the heap analyzer correspond to?
<script>
the label. S
haredFunctionInfos (SFI) is an object between a function and compiled code.
Functions usually have context, while SFI does not.
Many other objects appear to you to have been generated during the lifetime of your code, and they may contain event listeners and specific objects, as follows:
Q: Is there anything in Chrome that should be turned off in order not to affect my chart?
When using settings in Chrome DevTools, it is recommended to turn off all extensions in analytized mode or launch Chrome directly from a specific user data catalog (--user-data-dir=").
If you want charts to be as accurate as possible, apps, extensions, and even console logs can implicitly affect your charts.
Today's JavaScript engine automatically cleans up the garbage generated in your code in a variety of situations. T hat is, they can only do this, and there will still be memory leaks in our code due to logical problems. Use these tools to identify your bottleneck and remember not to guess it, but to test it.