Often we think of memory management as something on the back end, but if that’s not the case, the front end also needs to care about memory usage. Why does the front end need to care about memory? On the one hand, it prevents the page from being stuck or even not responding due to excessive memory usage; On the other hand, Node.js uses the V8 engine, and memory management is very important for the server. Because of the persistence of the server, memory is more likely to accumulate and cause memory overflow.
Js garbage collection mechanism
Js automatically manages memory through garbage collection. This approach has its own advantages and disadvantages:
- Benefits: greatly simplify the program are memory management code, reduce the burden of developers; It also reduces memory leaks caused by long running
- The bad: Developers have no control over memory management, we can’t force them to do garbage collection and manage it
Let’s take a look at some simple garbage collection strategies for JS:
1. Reference count
Currently, it is mainly used by browsers below Internet Explorer 8, which has been abandoned by modern browsers. Basic principle: Track the number of times each value is referenced, the number of times is referenced, plus one; When released, minus one; When it is zero, the memory occupied by the current value is freed.
2. Mark clearing
At present, the mainstream browsers at home and abroad all use tag clearing as a garbage collection strategy. Its strategy can be simply understood as:
- When a variable is entered into the environment (for example, declaring a variable in a function), mark the variable as “entered into the environment.” Logically, you can never free up memory occupied by variables that enter the environment, because they may be used whenever the execution stream enters the corresponding environment.
- When a variable leaves the environment, it is marked “out of the environment.”
We can tag variables in any way we want. For example, you can flip a particular bit to record when a variable entered the environment, or use a list of variables that entered the environment and a list of variables that left the environment to track which variable changed. The following example briefly reflects the definition of tag clearing:
function fn(){
let a = 'hello'; // Marked "enter environment"
let b = 'world'; // Marked "enter environment"
}
fn(); // After execution, a and B are marked "out of the environment" and recycled
Copy the code
The whole process can be summarized as follows:
- At run time, the garbage collector marks all variables stored in memory (of course, it can be marked in any way).
- It removes the tags of variables in the environment and those referenced by variables in the environment.
- Variables tagged thereafter are considered to be ready for deletion (because they are no longer accessible to variables in the environment).
- Finally, the garbage collector completes the memory cleanup, destroying the tagged values and reclaiming the memory they occupy.
V8 Memory control
Node is built on V8, and V8’s memory management mechanism, which is mainly used in the browser, can meet all the needs of the front page, but it limits the ability of developers to use as much memory as they want in Node. A Node can only use part of its memory, 1.4GB on a 64-bit system and 0.7GB on a 32-bit system. Under this limitation, Node cannot manipulate large memory objects, such as reading a 2GB file into memory, even though it has 64 GB of physical memory. In this case, we can use the Buffer class to complete the reading of large memory files. V8’s garbage collection strategy is based on a generational mechanism that divides memory space into new generation and old generation.
1. New generation memory
The new generation of memory has the following characteristics:
- The managed object has a short lifetime
- The space occupied is much smaller than the old generation space
- Frequent garbage collection
The Cheney algorithm is used to recycle the insane. The Cheney algorithm works as a typical space-for-time algorithm:
- Cenozoic space is divided into two Spaces called Semispace. The ones that are in use are called From Spaces, and the ones that are idle are called To Spaces. When we allocate objects, we allocate them first in the From space.
- When garbage collection begins, live objects in the From space are checked, copied To the To space, and memory in the From space is freed.
- After the copy is done, the From space is swapped with the To space
2. Old generation memory
Objects with a long lifetime in the new generation memory space will be copied to the old memory space. Objects that can be copied to the old memory space must meet the following conditions:
- Whether the object has been screcycled. If so, copy it directly To the old space, not To space.
- Whether the memory usage of the TO-space exceeds 25% of the to-space. Description When an object was copied From the From space To the To space, the memory usage of the To space exceeded the limit. Since the To space will become the From space, in order not To affect the subsequent memory allocation, will be directly promoted To the old space.
For the recycling of old generation memory, garbage collection is mainly carried out by combining mark-sweep and Mark-compact. Its working principle is as follows:
- In the marking phase, all objects are traversed and the living objects are marked; In the subsequent cleanup phase, only unmarked objects are cleared.
- To solve the problem of memory fragmentation, tokenization moves the living object to one end after the tag is complete, and then frees up space beyond the living object’s end.
3. Incremental marks
To avoid inconsistencies between the JavaScript application logic and what the garbage collector sees, the basic algorithm for garbage collection suspends the application logic and resumes it after garbage collection, a behavior known as “total pause.” A long “total pause” garbage collection can cause a significant lag in the user’s experience.
To reduce the pause time associated with garbage collection,V8 started with incremental marking, where actions that were supposed to be completed in one stop are broken down into many small “steps” that JavaScript uses for each one The application logic executes for a short time, and the garbage collection alternates with the application logic until the tagging phase is complete.
Reference article:
Node.js
www.ruanyifeng.com/blog/2017/0…