Review of recent original articles 😊 :

  • 1.2W word | Beginner intermediate Front-end JavaScript Self-test List-1
  • The Great Webpack HMR Study Guide (with source Code Analysis)
  • The Great Webpack Build Process Study Guide
  • WeakMap you Don’t Know
  • The Blob You Don’t Know
  • The Great Tsconfig. json Guide
  • “200 lines of JS code, take you to implement code compiler”

Learning chapter: WeakMap you Don’t Know

First, the main knowledge points

The article mainly reviews “JavaScript garbage collection mechanism”, “Map/WeakMap difference” and “WeakMap attribute and method”. It makes up for what I missed.

In addition, we can learn Set/WeakSet in the same way through the original text, and the effect will be better, which will also be introduced later in this paper.

Summary start, first look at the original outline:

Before introducing WeakMap, first review the garbage collection mechanism in JavaScript, which has a large relationship with the following WeakMap/WeakSet.

1. Garbage collection mechanism

Garbage Collection (abbreviated GC) is an automatic storage management mechanism. When a program occupies a portion of memory that is no longer accessible by the program, the program returns the portion of memory to the operating system through a garbage collection algorithm. The garbage collector can lighten the programmer’s burden and reduce errors in the program. Garbage collection has its roots in LISP. Many languages such as Smalltalk, Java, C#, and D support garbage collectors. JavaScript, as we know, has automatic garbage collection. In JavaScript, primitive type data is allocated to stack space, and reference type data is allocated to heap space.

1.1 Garbage collection in stack space

When the functionshowNameWhen the call is complete, move it downESP (Extended Stack Pointer)Pointer to destroyshowNameFunction, and then when other functions are called, the old memory will be overwritten and the execution context of another function will be stored to achieve garbage collection.



Image from How Browsers Work and Practice

1.2 Garbage collection in heap space

The basis for garbage collection strategies in The heap is The Generational Hypothesis. That is:

  1. Most objects live in memory for a very short time, and many quickly become inaccessible.
  2. Undead objects will live longer.

These two characteristics apply not only to JavaScript, but also to most dynamic languages, such as Java, Python, and so on. The V8 engine divides the heap space into new generation (short-lived objects) and old generation (long-lived objects) and uses different garbage collectors.

  • Secondary garbage collector, mainly responsible for the new generation of garbage recycling.
  • Main garbage collector, mainly responsible for old generation garbage collection.

Regardless of the type of garbage collector, the same garbage collection process is used: mark active and inactive objects, reclaim memory for inactive objects, and finally defragment memory.

1.2.1 Secondary garbage collector

The Cenozoic space is split 50-50 into two areas, an object area and a free area, using the Scavenge algorithm.



Image from How Browsers Work and Practice

Execution process:

  • The new object exists in the object area, and when the object area is about to be full, a garbage collection is performed;
  • In garbage collection, the garbage in the object area is marked, and then the sub-garbage collector copies and arranges the surviving objects into the free area, which is equivalent to memory defragmenting.
  • After the copy is completed, the object area and the free area are flipped to complete the garbage collection operation, which also allows the two areas in the new generation to be reused indefinitely.

Of course, there are some problems: if the data of the replication operation is large, the cleaning efficiency will be affected. The solution of the JavaScript engine is to make the new generation area small and use the object promotion strategy (after two recollections, the surviving objects will be moved to the old area) to avoid the problem of the living objects filling the whole area because the new generation area is small.

1.2.2 Main garbage collector

It is divided into mark-sweep algorithm and Mark-compact algorithm. A) Mark-sweep algorithm process:

  • Tagging process: start with a set of root elements and walk through the entire element. The elements that can be reached are active objects, or garbage data.
  • Cleanup process: Clean up marked data and generate a large amount of fragmented memory. (Disadvantages: Large objects cannot be allocated enough contiguous memory)



Image from How Browsers Work and Practice



B) Mark-compact algorithm

Process:

  • Tagging process: start with a set of root elements and walk through the entire element. The elements that can be reached are active objects, or garbage data.
  • Cleanup process: Move all surviving objects to a segment, then clear the contents beyond the end boundary.



Image from How Browsers Work and Practice

1.3 Extended Reading

1. Illustrated Java Garbage Collection Mechanism 2. MDN Memory Management

2. Map VS WeakMap

2.1 Main differences between Map and WeakMap

WeakMap structure is similar to Map structure and is also used to generate a set of key-value pairs. The difference between:

  • MapThe key of an object can be any type, butWeakMapKeys in an object can only be object references (nullExcept);
const map = new WeakMap(a);

map.set(1.2)

// TypeError: 1 is not an object!

map.set(Symbol(), 2)

// TypeError: Invalid value used as weak map key

map.set(null.2)

// TypeError: Invalid value used as weak map key

Copy the code
  • WeakMapCannot contain objects that are not referenced, otherwise they will be automatically purged from the collection (garbage collection);
  • WeakMapObjects have nosizeProperty, which is not enumerable, cannot get the size of the collection.
const map = new WeakMap(a);

const user1 = {name'leo'};

const user2 = {name'pingan'};

map.set(user1, 'good~');

map.set(user2, 'hello');

map.map(item= > console.log(item))

//Uncaught TypeError: map.map is not a function

Copy the code

2.2 Map disadvantages and WeakMap advantages

1. Both assignment and search operations are O(n) time, because both operations require traversing the entire array to match. 2. Memory leaks can occur because arrays keep referencing every key and value. WeakMap, by contrast, holds a “weak reference” to each key object, meaning garbage collection works correctly when no other reference exists. The structure of the native WeakMap is special and efficient, and the key it uses for mapping is valid only if it is not reclaimed.

2.3 Comparison of garbage collection between Map and WeakMap

When the amount of data is larger, the garbage collection effect is more obvious. Run node — expose-GC weakmap.js on the command line to view the comparison effect. The — expose-GC parameter allows manual garbage collection.

// weakmap.js

const objNum = 10 * 1024 * 1024;

const useType = 1// Change useType value to test Map and WeakMap

const curType = useType == 1 ?"【Map】 : [WeakMap]";

let arr = new Array(objNum);



function usageSize({

    const used = process.memoryUsage().heapUsed;

    return Math.round((used / 1024 / 1024) * 100) / 100 + "M";

}



if (useType == 1) {

    global.gc();

    console.log(objNum + '个' + curType + 'Memory occupied:' + usageSize());



    const map = new Map(a);

    map.set(arr, 1);



    global.gc();

    console.log(objNum + '个' + curType + 'Memory occupied:' + usageSize());



    arr = null;

    global.gc();

    console.log(objNum + '个' + curType + 'Memory occupied:' + usageSize());



    console.log("= = = = =")

else {

    global.gc();

    console.log(objNum + '个' + curType + 'Memory occupied:' + usageSize());



    const map = new WeakMap(a);



    global.gc();

    console.log(objNum + '个' + curType + 'Memory occupied:' + usageSize());



    arr = null;

    global.gc();

    console.log(objNum + '个' + curType + 'Memory occupied:' + usageSize());



    console.log("= = = = =")

}

Copy the code

3. Introduction and application of WeakMap

3.1 introduce WeakMap

A WeakMap object is a set of key/value pairs where the keys are weakly referenced. The key of WeakMap can only be Object. Primitive data types cannot be used as keys (such as Symbol). WeakMap has only four methods available: get(), set(), has(), and delete(). For detailed description of properties and methods, see MDN WeakMap.

3.2 WeakMap application

The paper introduces two application scenarios of “caching calculation results through WeakMap” and “reserving private data in WeakMap”. Another more common scenario is the DOM node as the key name. Scenario 1: WeakMap is used when we want to add data to the DOM. The advantage is that when the DOM element is removed, the corresponding WeakMap record is also automatically removed:

<div id="WeakMap"></div>

Copy the code
const wm = new WeakMap(a);

const weakMap = document.getElementById('WeakMap');

wm.set(weakMap, 'some information');

wm.get(weakMap) //"some information"

Copy the code

Scenario 2: This is used when we want to add event listeners to DOM elementsWeakMap

<button id="button1">Button 1</button>

<button id="button2">Button 2</button>

Copy the code
const button1 = document.getElementById('button1');

const button2 = document.getElementById('button2');

const handler1 = (a)= > {  console.log("Button1 was clicked.")};

const handler2 = (a)= > {  console.log("Button2 was clicked")};



/ / code 1

button1.addEventListener('click', handler1, false);

button2.addEventListener('click', handler2, false);

 

/ / code 2

const listener = new WeakMap(a);

 

listener.set(button1, handler1);

listener.set(button2, handler2);

 

button1.addEventListener('click', listener.get(button1), false);

button2.addEventListener('click', listener.get(button2), false);

Copy the code

The advantage of Code 2 over Code 1 is that since the listener function is placed inside WeakMap, once the DOM object button1 / Button2 disappears, the listener functions handler1 and Handler2 bound to it will also disappear automatically.

Second, expand knowledge

1. To expand the Set/WeakSet

1.1 Main differences between Set and WeakSet

WeakSet structure is similar to Set, which is also a collection of non-repeating values. The difference between:

  • WeakSetCan only be objects, not other types of values;
const ws = new WeakSet(a);

ws.add(1)

// TypeError: Invalid value used in weak set

ws.add(Symbol())

// TypeError: invalid value used in weak set

Copy the code
  • WeakSetAre weak references, which are not considered by the garbage collection mechanismWeakSetA reference to the object;
  • WeakSetObjects have nosizeProperty, which is not enumerable, cannot get the size of the collection.

1.2 Comparison of Set/WeakSet garbage recovery

Execute node — expose-GC weakset.js through the command line to view the comparison effect.

// weakset.js

const objNum = 5000 * 1024;

const useType = 1;

const curType = useType == 1 ?【Set】 : "【WeakSet】";

let obj = [];

for (let k = 0; k < objNum; k++) {

    obj[k] = {}

}



function usageSize({

    const used = process.memoryUsage().heapUsed;

    return Math.round((used / 1024 / 1024) * 100) / 100 + "M";

}



if (useType == 1) {

    global.gc();

    console.log(objNum + '个' + curType + 'Memory occupied:' + usageSize());



    const sets = new Set([...obj]);



    global.gc();

    console.log(objNum + '个' + curType + 'Memory occupied:' + usageSize());



    obj = null;

    global.gc();

    console.log(objNum + '个' + curType + 'Memory occupied:' + usageSize());



    console.log("= = = = =")

else {

    global.gc();

    console.log(objNum + '个' + curType + 'Memory occupied:' + usageSize());



    const sets = new WeakSet(obj);



    global.gc();

    console.log(objNum + '个' + curType + 'Memory occupied:' + usageSize());



    obj = null;

    global.gc();

    console.log(objNum + '个' + curType + 'Memory occupied:' + usageSize());



    console.log("= = = = =")

}

Copy the code

Third, summary

This paper first reviewed the core knowledge points in “WeakMap you don’t know”, reviewed “garbage collection mechanism”, “Map VS WeakMap” and “WeakMap introduction and application”, and finally extended the review of “Set/WeakSet” related knowledge points. In real business development, it is also a good idea to consider the proper use of garbage collection, which is a very common way to improve product performance.

Language knowledge base: cute-frontend Public account: front-end self-study class