Map与WeakMap简单区别
1 2
| Map的键值可以是原始数据类型和引用类型,WeakMap的键值只能说引用类型(object) Map可以迭代遍历键,WeakMap不可迭代遍历键
|
Map 与 WeakMap 使用内存情况
1.WeakMap 内存占用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
|
global.gc() console.log(`第一次垃圾回收,当前内存使用情况:${(process.memoryUsage().heapUsed / 1024 / 1024).toFixed(2)}MB`) const wm = new WeakMap()
let key = {}
wm.set(key, new Array(114514 * 19))
global.gc() console.log(`第二次垃圾回收,当前内存使用情况:${(process.memoryUsage().heapUsed / 1024 / 1024).toFixed(2)}MB`)
key = null
global.gc() console.log(`第三次垃圾回收,当前内存使用情况:${(process.memoryUsage().heapUsed / 1024 / 1024).toFixed(2)}MB`)
|
2.Map 内存占用
同上,只不过是将
1
| const wm = new WeakMap();
|
替换为
结果为
比较1、2例子可以发现,当引用类型key的值指向为空的时候,使用WeakMap的时候会立即释放内存
当使用Map的时候不会立即释放内存。
当然,如果在 2例子里面起一个定时器,每隔100ms定时打印内存情况,会发现,即使使用Map,过一段时间内存也会被释放掉
这是因为 javascript 引擎做了优化,会定期清理内存。
1 2 3 4 5 6 7 8 9 10 11 12
| setInterval(() => { console.log(`第N次垃圾回收,当前内存使用情况:${(process.memoryUsage().heapUsed / 1024 / 1024).toFixed(2)}MB`); }, 100)
|
虽然,javascript引擎会自动优化内存,但是作为开发者还是应该适当关注一下内存的使用情况,以防止极端的情况内存释放不及时。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
|
global.gc(); console.log( `第一次垃圾回收,当前内存使用情况:${(process.memoryUsage().heapUsed / 1024 / 1024).toFixed(2)}MB` ); const m = new Map();
let key = {}; m.set(key, new Array(114514 * 19));
global.gc(); console.log( `第二次垃圾回收,当前内存使用情况:${(process.memoryUsage().heapUsed / 1024 / 1024).toFixed(2)}MB, 当前Map的长度: ${m.size}` );
key = null; global.gc(); console.log( `第三次垃圾回收,当前内存使用情况:${(process.memoryUsage().heapUsed / 1024 / 1024).toFixed(2)}MB, 当前Map的长度: ${m.size}` );
m.clear();
global.gc(); console.log( `第四次垃圾回收,当前内存使用情况:${(process.memoryUsage().heapUsed / 1024 / 1024).toFixed(2)}MB, 当前Map的长度: ${m.size}` );
|
附录
使用 node 命令执行js的时候加入 –expose-gc参数的作用
1
| --expose-gc 参数表示允许手动执行垃圾回收机制
|
相关链接
WeakSet 用法解惑
通过垃圾回收机制来了解Map与WeakMap