Table of Contents
What is a memory leak? " >What is a memory leak?
JavaScript Memory Management" >JavaScript Memory Management
JavaScript Memory Leak
Mark-and-sweep" >Mark-and-sweep
Three types of common JavaScript memory leaks
1: Unexpected global variables" >1: Unexpected global variables
2: The forgotten timer or callback function" >2: The forgotten timer or callback function
3: Detaching references from the DOM" >3: Detaching references from the DOM
4: Closures" >4: Closures
Overview of Chrome Memory Profiling Tools
Timeline" >Timeline
Profiles" >Profiles
Example: Use Chrome to find memory leaks
Find out cyclically growing memory" >Find out cyclically growing memory
Save two snapshots" >Save two snapshots
Record heap allocations Find memory leaks" >Record heap allocations Find memory leaks
Another useful feature" >Another useful feature
Home Web Front-end JS Tutorial How to deal with javascript memory leaks

How to deal with javascript memory leaks

Jul 15, 2021 pm 03:30 PM
javascript

Processing method: 1. Assign null or reassign other values ​​after use; 2. Use modern garbage collection algorithms; 3. Be careful when saving DOM element references; 4. Pass SessionStack , playback problems in the application to avoid memory leaks and increase the memory usage of the entire application.

How to deal with javascript memory leaks

The operating environment of this tutorial: windows7 system, javascript version 1.8.5, Dell G3 computer. ,

Memory leaks are a problem that every developer will eventually face. It is the source of many problems: slow response, crashes, high latency, and other application problems.

What is a memory leak?

Essentially, a memory leak can be defined as: when the application no longer needs to occupy the memory, for some reason, the memory is not reclaimed by the operating system or the available memory pool. Programming languages ​​vary in how they manage memory. Only developers know best which memory is no longer needed and can be reclaimed by the operating system. Some programming languages ​​provide language features that help developers do this kind of thing. Others rely on developers to be clear about whether memory is needed.

JavaScript Memory Management

JavaScript is a garbage collected language. Garbage collection languages ​​help developers manage memory by periodically checking whether previously allocated memory is reachable. In other words, garbage-collected languages ​​alleviate the "memory is still available" and "memory is still reachable" problems. The difference between the two is subtle but important: only the developer knows which memory will still be used in the future, while unreachable memory is algorithmically determined and marked, and is promptly reclaimed by the operating system.

JavaScript Memory Leak

The main cause of memory leaks in garbage collected languages ​​is unwanted references. Before understanding it, you need to understand how the garbage collection language distinguishes between reachable and unreachable memory.

Mark-and-sweep

The algorithm used by most garbage collection languages ​​is called Mark-and-sweep. The algorithm consists of the following steps:

  • The garbage collector creates a list of "roots". Roots are usually references to global variables in your code. In JavaScript, the "window" object is a global variable and is treated as root. The window object always exists, so the garbage collector can check that it and all its child objects exist (i.e. are not garbage);

  • All roots are checked and marked as active (i.e. not garbage) Not garbage). All sub-objects are also checked recursively. If all objects starting from root are reachable, they are not considered garbage.

  • All unmarked memory will be treated as garbage, and the collector can now release the memory and return it to the operating system.

Modern garbage collectors have improved algorithms, but the essence is the same: reachable memory is marked, and the rest is garbage collected.

Unnecessary reference means that the developer knows that the memory reference is no longer needed, but for some reason, it is still left in the active root tree. In JavaScript, an unwanted reference is a variable that remains in the code and is no longer needed but points to a piece of memory that should be freed. Some people think this is a developer error.

To understand the most common memory leaks in JavaScript, we need to understand how references are easily forgotten.

Three types of common JavaScript memory leaks

1: Unexpected global variables

JavaScript handles undefined variables in a looser way: undefined The variable will create a new variable in the global object. In browsers, the global object is window .

The truth is:

Function foo forgot to use var internally and accidentally created a global variable. This example leaks a simple string, which is innocuous, but there are worse things.

Another unexpected global variable may be created by this:

Add 'use strict' at the beginning of the JavaScript file , can avoid such errors from occurring. Enable strict mode parsing of JavaScript to avoid unexpected global variables.

Global Variable Notes

Although we discussed some unexpected global variables, there are still some garbage generated by explicit global variables. They are defined as non-recyclable (unless defined as empty or reallocated). Care needs to be taken especially when global variables are used to temporarily store and process large amounts of information. If you must use a global variable to store a large amount of data, be sure to set it to null or redefine it after use. One major cause of increased memory consumption related to global variables is caching. Caching data is for reuse, and the cache must have an upper limit on its size to be useful. High memory consumption causes the cache to breach its upper limit because cached content cannot be reclaimed.

2: The forgotten timer or callback function

Using setInterval in JavaScript is very common. A common piece of code:

What this example illustrates: the timer associated with the node or data is no longer needed, the node object can be deleted, and the entire callback function is no longer needed. However, the timer callback function has still not been recycled (it will not be recycled until the timer stops). At the same time, someResource cannot be recycled if a large amount of data is stored.

In the case of observers, it is important to explicitly remove them once they are no longer needed (or the associated object becomes unreachable). The old IE 6 cannot handle circular references. Today, most browsers can recycle observer handlers once the observer object becomes unreachable, even without explicitly removing them.

Observer code example:

Object observer and circular reference considerations

Old versions of IE cannot detect DOM nodes and JavaScript code. Circular references between them will cause memory leaks. Today, modern browsers (including IE and Microsoft Edge) use more advanced garbage collection algorithms and can correctly detect and handle circular references. In other words, when recycling node memory, there is no need to call removeEventListener.

3: Detaching references from the DOM

Sometimes, it is useful to save the internal data structure of a DOM node. If you want to quickly update several rows of a table, it makes sense to save each row of DOM as a dictionary (JSON key-value pair) or array. At this point, there are two references to the same DOM element: one in the DOM tree and the other in the dictionary. When you decide to delete these rows in the future, you will need to clear both references.

In addition, reference issues within the DOM tree or subnodes must also be considered. Suppose your JavaScript code stores a reference to a <td> in the table. When you decide to delete the entire table in the future, you intuitively think that the GC will recycle other nodes except the saved <td>. This is not the actual situation: this <td> is a child node of the table, and the child element has a reference relationship with the parent element. Because the code retains a reference to <td>, the entire table remains in memory. Be careful when saving references to DOM elements.

4: Closures

Closures are a key aspect of JavaScript development: anonymous functions can access variables in the parent scope.

Code example:

The code snippet does one thing: every time replaceThing is called, theThing gets an array containing a large array and a new A new object of closure (someMethod). At the same time, the variable unused is a closure that references originalThing (the previous replaceThing called theThing). Are your thoughts confused? The most important thing is that once a closure's scope is created, they have the same parent scope and the scope is shared. someMethod is available through theThing, and someMethod shares the closure scope with unused, even though unused is never used , the originalThing it references forces it to remain in memory (preventing it from being recycled). When this code is run repeatedly, you will see that the memory usage continues to increase, and the garbage collector (GC) cannot reduce the memory usage. Essentially, a linked list of closures has been created, and each closure scope carries an indirect reference to a large array, causing a serious memory leak.

Meteor's blog post explains how to fix this problem. Add originalThing = null at the end of replaceThing.

Overview of Chrome Memory Profiling Tools

Chrome provides a great set of tools for detecting JavaScript memory usage. Two important tools related to memory: timeline and profiles.

Timeline

timeline can detect unwanted memory in your code. In this screenshot, we can see the steady growth of potential leaked objects. At the end of the data collection, the memory usage is significantly higher than at the beginning of the collection, and the total number of Nodes is also very high. There are various signs that there are DOM node leaks in the code.

Profiles

Profiles is a tool you can spend a lot of time focusing on, it can save snapshots, compare different snapshots of JavaScript code memory usage, and also record time distribution. Each result contains different types of lists, the ones related to memory leaks are summary lists and comparison lists.

summary (Summary) List shows the allocation and total size of different types of objects: shallow size (the total size of all objects of a specific type), retained size (shallow size plus other associated with it) object size). It also provides an idea of ​​how far an object is from its associated GC root.

Compare the comparison list of different snapshots to find memory leaks.

Example: Use Chrome to find memory leaks

There are essentially two types of leaks: leaks caused by periodic memory growth, and occasional memory leaks. Obviously, periodic memory leaks are easy to find; occasional leaks are more difficult and are generally easily ignored. Occasionally occurring memory leaks may be considered an optimization problem, while recurring ones are considered bugs that must be resolved.

Take the code in the Chrome document as an example:

When grow is executed, p nodes are created and inserted into the DOM, and a huge is assigned to the global variable. array. A steady increase in memory can be detected using the tools mentioned above.

Find out cyclically growing memory

The timeline tag is good at doing this. Open the example in Chrome, open Dev Tools, switch to timeline, check memory and click the record button, then click the The Button button on the page. Stop recording after a while and see the results:

Two signs show that there is a memory leak, Nodes (green line) and JS heap (blue line) in the picture. Nodes are growing steadily and not declining, which is a significant sign.

The memory usage of JS heap is also growing steadily. Not so easy to find due to the garbage collector. The picture shows that the memory usage rises and falls. In fact, after each drop, the size of the JS heap is larger than before. In other words, although the garbage collector continues to collect memory, the memory is still leaked periodically.

After confirming that there is a memory leak, we find the root cause.

Save two snapshots

Switch to the profiles tab of Chrome Dev Tools, refresh the page, and after the page refresh is complete, click Take Heap Snapshot to save the snapshot as a baseline. Then click the The Button button again, wait a few seconds, and save the second snapshot.

Select Summary in the filter menu, select Objects allocated between Snapshot 1 and Snapshot 2 on the right, or select Comparison in the filter menu, and then you can see a comparison list.

It is easy to find a memory leak in this example. Take a look at the (string) Size Delta Constructor, 8MB, 58 new objects. The new object is allocated, but not released, occupying 8MB.

If you expand the (string) Constructor, you will see many individual memory allocations. Selecting an individual allocation, the following retainers will draw our attention.

The allocation we have selected is part of an array associated with the x variable of the window object. This shows the complete path from the huge object to the root (window) that cannot be recycled. We've found the potential leak and where it came from.

Our example is relatively simple, only a small number of DOM nodes are leaked, which is easy to find using the snapshot mentioned above. For larger sites, Chrome also offers the Record Heap Allocations feature.

Record heap allocations Find memory leaks

Go back to the profiles tab of Chrome Dev Tools and click Record Heap Allocations. When the tool is running, pay attention to the blue bar at the top, which represents memory allocation. There is a large amount of memory allocation every second. It runs for a few seconds and then stops.

You can see the tool’s trump card in the picture above: select a certain timeline and you can see the memory allocation during this time period. Choosing a timeline as close to the peak as possible, the list below shows only three constructors: one is the most leaked (string), the next is the associated DOM allocation, and the last one is Text constructor (the text contained by the DOM leaf node).

Select a HTMLpElement constructor from the list and then select Allocation stack.

Now you know where the elements are allocated (grow -> createSomeNodes). Look carefully at the timeline in the picture and find HTMLpElement The constructor is called many times, which means that the memory has been occupied and cannot be recycled by GC. We know the exact location where these objects are allocated (createSomeNodes). Back to the code itself, let's discuss how to fix the memory leak.

Another useful feature

In the heap allocations results area, select Allocation.

This view presents a list of functions related to memory allocation, and we immediately see grow and createSomeNodes. When grow is selected, looking at the relevant object constructor, it is clear that (string), HTMLpElement and Text are leaked.

Combined with the tools mentioned above, you can easily find memory leaks.

[Recommended learning: javascript advanced tutorial]

The above is the detailed content of How to deal with javascript memory leaks. For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

How to implement an online speech recognition system using WebSocket and JavaScript How to implement an online speech recognition system using WebSocket and JavaScript Dec 17, 2023 pm 02:54 PM

How to use WebSocket and JavaScript to implement an online speech recognition system Introduction: With the continuous development of technology, speech recognition technology has become an important part of the field of artificial intelligence. The online speech recognition system based on WebSocket and JavaScript has the characteristics of low latency, real-time and cross-platform, and has become a widely used solution. This article will introduce how to use WebSocket and JavaScript to implement an online speech recognition system.

WebSocket and JavaScript: key technologies for implementing real-time monitoring systems WebSocket and JavaScript: key technologies for implementing real-time monitoring systems Dec 17, 2023 pm 05:30 PM

WebSocket and JavaScript: Key technologies for realizing real-time monitoring systems Introduction: With the rapid development of Internet technology, real-time monitoring systems have been widely used in various fields. One of the key technologies to achieve real-time monitoring is the combination of WebSocket and JavaScript. This article will introduce the application of WebSocket and JavaScript in real-time monitoring systems, give code examples, and explain their implementation principles in detail. 1. WebSocket technology

How to use JavaScript and WebSocket to implement a real-time online ordering system How to use JavaScript and WebSocket to implement a real-time online ordering system Dec 17, 2023 pm 12:09 PM

Introduction to how to use JavaScript and WebSocket to implement a real-time online ordering system: With the popularity of the Internet and the advancement of technology, more and more restaurants have begun to provide online ordering services. In order to implement a real-time online ordering system, we can use JavaScript and WebSocket technology. WebSocket is a full-duplex communication protocol based on the TCP protocol, which can realize real-time two-way communication between the client and the server. In the real-time online ordering system, when the user selects dishes and places an order

How to implement an online reservation system using WebSocket and JavaScript How to implement an online reservation system using WebSocket and JavaScript Dec 17, 2023 am 09:39 AM

How to use WebSocket and JavaScript to implement an online reservation system. In today's digital era, more and more businesses and services need to provide online reservation functions. It is crucial to implement an efficient and real-time online reservation system. This article will introduce how to use WebSocket and JavaScript to implement an online reservation system, and provide specific code examples. 1. What is WebSocket? WebSocket is a full-duplex method on a single TCP connection.

JavaScript and WebSocket: Building an efficient real-time weather forecasting system JavaScript and WebSocket: Building an efficient real-time weather forecasting system Dec 17, 2023 pm 05:13 PM

JavaScript and WebSocket: Building an efficient real-time weather forecast system Introduction: Today, the accuracy of weather forecasts is of great significance to daily life and decision-making. As technology develops, we can provide more accurate and reliable weather forecasts by obtaining weather data in real time. In this article, we will learn how to use JavaScript and WebSocket technology to build an efficient real-time weather forecast system. This article will demonstrate the implementation process through specific code examples. We

Simple JavaScript Tutorial: How to Get HTTP Status Code Simple JavaScript Tutorial: How to Get HTTP Status Code Jan 05, 2024 pm 06:08 PM

JavaScript tutorial: How to get HTTP status code, specific code examples are required. Preface: In web development, data interaction with the server is often involved. When communicating with the server, we often need to obtain the returned HTTP status code to determine whether the operation is successful, and perform corresponding processing based on different status codes. This article will teach you how to use JavaScript to obtain HTTP status codes and provide some practical code examples. Using XMLHttpRequest

How to use insertBefore in javascript How to use insertBefore in javascript Nov 24, 2023 am 11:56 AM

Usage: In JavaScript, the insertBefore() method is used to insert a new node in the DOM tree. This method requires two parameters: the new node to be inserted and the reference node (that is, the node where the new node will be inserted).

JavaScript and WebSocket: Building an efficient real-time image processing system JavaScript and WebSocket: Building an efficient real-time image processing system Dec 17, 2023 am 08:41 AM

JavaScript is a programming language widely used in web development, while WebSocket is a network protocol used for real-time communication. Combining the powerful functions of the two, we can create an efficient real-time image processing system. This article will introduce how to implement this system using JavaScript and WebSocket, and provide specific code examples. First, we need to clarify the requirements and goals of the real-time image processing system. Suppose we have a camera device that can collect real-time image data

See all articles