There are a lot of information about WeakMap, which can be referred to:
ES6 Tutorial
ES6 series WeakMap
This article focuses on how to understand the concept of “weak reference”
Weak references vs strong references
We understand the difference between weak and strong references by comparing WeakMap and Map:
var m = new Map(a)function Foo() {
this.arr = new Array(5 * 1024 * 1024)}var f = new Foo()
m.set(f, 'data')
Copy the code
var wm = new WeakMap(a)function Foo() {
this.arr = new Array(5 * 1024 * 1024)}var f = new Foo()
wm.set(f, 'data')
Copy the code
The memory model for the above two pieces of code can be expressed roughly as follows:
In Figure 1, because Foo object is referenced by both F and Map object, its reference count is 2. In Figure 2, because it is referenced by WeakMap object, it is a weak reference and is not included in the reference count, so its value is 1.
Weak references and garbage collection
If we break f’s reference to Foo, Foo will be collected by the garbage collector because its reference count is zero.
var wm = new WeakMap(a)function Foo() {
this.arr = new Array(5 * 1024 * 1024)}var f = new Foo()
wm.set(f, 'data')
f = null
Copy the code
To verify that WeakMap works, we usually try to print wm.get(f), which is undefined:
var wm = new WeakMap(a)function Foo() {
this.arr = new Array(5 * 1024 * 1024)}var f = new Foo()
wm.set(f, 'data')
f = null
console.log(wm.get(f)) // undefined
Copy the code
The results met expectations, very good!
It would be naive if it ended there. As in the above code, we changed WeakMap to Map, and found that the result was undefined.
Why is that? When wm. Get (f) is executed, wm. Get (null) is executed. WeakMap or Map is always undefined. In fact, when F disconnects from Foo, the only channel to Foo is cut off. This creates a paradoxical situation: to make an object recyclable, all references must be broken; WeakMap requires a reference to the object to perform get.
So how do you verify that WeakMap works?
How do I verify that WeakMap works
How to validate in NodeJS is already covered in this article, but here’s another way to validate in browsers:
In Chrome, we can use the Developer Tools memory panel to debug Map. Let’s start by debugging Map:
- Execute the following code on the console
var m = new Map(a)function Foo() {
this.arr = new Array(5 * 1024 * 1024)}var f = new Foo()
m.set(f, 'data')
f = null
Copy the code
- Click on the
memory
Panel in the small dot, record the current memory snapshot, searchFoo
, found the existence of a visibleFoo
The object was not collected.
Then try WeakMap again:
- Execute the following code on the console
var wm = new WeakMap(a)function Foo() {
this.arr = new Array(5 * 1024 * 1024)}var f = new Foo()
wm.set(f, 'data')
f = null
Copy the code
- Click on the
memory
Panel in the small dot, record the current memory snapshot, searchFoo
, it does not exist, so it has been reclaimed.
conclusion
I always think WeakMap should be a very simple thing, but a little deeper still dig out a lot of knowledge points, I really dare not “despise” any knowledge in the future.