Recovery mechanism process

  1. Memory is divided into new generation, old generation
  2. The new generation uses the Scavenge algorithm for recycling
    • The memory is divided into From, To two Spaces;
    • Garbage collection starts by checking whether objects in From are alive or non-alive. The live objects are copied To the To space, which holds these live objects, and the non-live objects are released.
    • The Form and To are recycled the next time the Scavenge avenge the From exploiture, the Form and To be recycled the next time the From exploiture is tested again, repeat step 2, and if the surviving object in the From is not released From the Scavenge avenge. Objects are considered long-lived and promoted To the old generation memory, or To space has been used more than 25%, that is promoted To the old generation.
  3. The old generation of Mark – sweep&Mark – compact
    • In the mark-sweep phase, only surviving objects are marked, and other unmarked objects are cleared during the mark-sweep phase.
    • The cleared objects will form scattered memory blocks in the memory. After mark-sweep, the space of dead objects will be mark-compact to the right of living objects 👉, and the space on the right of living objects will be cleared directly.
    • Incremental Marking is used in the Marking phase to enable the execution of application logic while Marking, so as to minimize the blocking of JS logic. (Although the incremental tag makes the overall garbage collection process more time-consuming, the implementation of the program)

Avoid Memory leaks

The global variable

When a variable is defined in a global scope, it is automatically mounted to the Window object. When garbage collected, the object is considered to be referenced by the Window object, so it will not be marked out and will remain in memory.

As in the console inputvar a = 100
function b() { console.log('b')}window.a = 100
Copy the code

Solution: do not use global variables as much as possible. If necessary, set them to NULL before the program finishes execution, such as a= NULL

Listener, timer

Listen for an eventwindowAddEventListener () timeconst a = 0;
const b = function() {
    a++
};
window.setInterval(b, 1000);
Copy the code

Solution: use the window. The removeEventListener () to remove the listener, the window, clearInterval () to remove the timer, can be in the program manual removal, removed before or after the program execution, such as vuebeforeDestroy component destroyed before listening, removed the timer.

closure

The scope of an inner function that accesses its outer function forms a closure, and closures are rarely used

function a() {
    let b = 'b';
    return function c() {
        console.log(b)}} c will always have references to bCopy the code

Dom binding

let btn = $('#btn')
btn.onclick = (event) = > { console.log(event.target)} reference to BTN:1, BTN. Onclick -- -- > BTN2Target -- > BTN BTN =nullOnly the reference to btn.onclick is clear, but there is always a DOM reference to event.target === BTN.Copy the code

Solution: remove dom elements, the document. The body. RemoveChild (BTN)

A weak reference WeakMap

A weak reference means that the reference to the object by the key name is not taken into account in the garbage collection process. As long as the referenced object has no other references, the garbage collection mechanism will release the memory occupied by the object

// Map is a strong reference, the key value is null, Map still holds the reference to the key, there is a memory leak problem
let map = new Map(a)let key = new Array(1000000).fill(0)
map.set(key, 1)
key = null

// If the key value is null, the weak key value will be deleted automatically
let weak = new WeakMap(a)let key = new Array(1000000).fill(0)
weak.set(key, 1)
key = null
Copy the code

HeapUsed does not clear memory when key=null is executed.

node --expose-gc
global.gc() // Manually perform gc garbage collection
process.memoryUsage() // Check the current memory usage
let map = new Map(a)let key = new Array(1000000).fill(0)
map.set(key, 1)
global.gc()
process.memoryUsage()
// Select * from memory
key = null
global.gc()
process.memoryUsage()
Copy the code

The resources

Nodejs

Find out about garbage collection for V8 engines