Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”. This article has participated in the “Digitalstar Project” and won a creative gift package to challenge the creative incentive money.
During the National Day holiday, I actively responded to the epidemic prevention policy in Xiamen and studied hard at home. New information about the garbage collection mechanism of the JS engine V8 used in Chrome and Node.js is shared here. This article continues with V8’s old generation algorithm mark-Sweep & Mark-Compact, how the new generation gets promoted to the old generation, and how to view and expand V8 memory. If you have any inadequacies or suggestions, you are welcome to correct them
Mark-sweep & Mark-Compact
mark-sweep
The algorithm used in the early days of the V8 engine, the tag clearing algorithm. First, the garbage collection mechanism will have a root node, GC Roots (note that the root node is not the browser environment)window
Or the Node environmentglobal
), all variables are referenced by the root node. The old generation of garbage collection, the start will be scanning width, then variables associated with GC Roots are marked (below red rectangle block), the rest of the variables have no marked (below the gray rectangular blocks) will be considered waste objects, in the sweep phase by GC, new variables can store (below white rectangular blocks). The illustration is as follows:
mark-compact
The algorithm now used by the V8 engine, the mark-up algorithm. It also does a sweep first and flags useful variables, and instead of mark-sweep, it does a sweep of variables first, moving the surviving variables together to create contigual memory (which makes it easier to store contigual objects such as arrays). Finally, the objects in the rest of the space are cleared.
Note that it is tidied up and then cleared, not tidied up and then cleaned up. Because the garbage object in the corresponding position will be overwritten when the live variable is moved, the workload of cleaning will be reduced and the efficiency will be higher.
Total pause mark and increment mark + tricolor mark method
Early V8 engines used full stop marking, which means all at once. The incremental tag + tricolor tag is now used, with threads switching more frequently but with fewer layers per tag. For example, the first time you switch from running code to GC, just mark the first layer, mark that layer gray, then mark the next layer associated with it black, and then go back to the main thread code and continue running. The next time you switch to GC, start the scan directly on the last grayed node as the root node, mark it white, grayed the last grayed node, black the next layer associated with it, and then go back to the main thread to run the code again. This alternates, and the last variables whittled are those that need to be preserved. This will make each GC execution time very short and unnoticeable.
The new generation rose to the old generation
There are two conditions for promotion:
- The Semi Space From which objects are recycled or reproduced.
- Semi Space To Space usage has exceeded 25%
Compared with Cenozoic, objects in old age are more stable and live longer.
Check memory usage
The browser
Can be directly in the Chrome console input window. Performance. The memory view:
Notice it’s in b, and when you convert it to MB you see it’s 2072MB, which is about 2GB
In the node
You can use process.memoryusage () to get an object of the memoryUsage(in units b) of the node.js process.
The following explanation is from node.js v16.10.0 documentation:
- RSS, or resident set size, is the amount of space that a process occupies in the main memory device (a subset of the total allocated memory), including all C++ and JavaScript objects and code.
- HeapTotal and heapUsed refer to V8’s memory usage.
- External refers to the memory usage of C++ objects bound to V8 managed JavaScript objects.
Expand the memory
For example, if you want to expand the memory to 4GB, you can run node –max-old-space-size=4096 at startup to execute the file.js, in MB. By the way, variables in global objects are not garbage collected and persist until the end of the current thread, so try not to define variables in global objects.