一、GC(垃圾回收机制)?
GC就是指垃圾回收机制,JavaScript里垃圾数据是不用手动清除,JS引擎中有个后台进程称为垃圾回收器,它监视所有的对象,观察对象是否可以被访问,然后按照固定的时间间隔周期性的删除掉那些不可访问的对象,常用的垃圾回收算法有:引用计数法和标记清除法。
引用计数法
引用计数法就是给占用物理内存空间的对象附加一个计数器,当有其他的对象引用这个对象的时候计数器就加1,如果解除引用了就把计数器减1,当最后计数器为0的时候就会将该对象所占用的物理空间回收掉,此时就不可以反问这个对象了。
引用计数很简单,但是它无法清除掉被循环引用的数据,如下:
function f() { var o1 = {}; var o2 = {}; o1.p = o2; // o1引用o2 o2.p = o1; // o2引用o1 } f();
为了解决引用计数的问题,又引出了标记清除法。
标记清除法
标记清除法分为两个阶段:
- 标记阶段:标记阶段就是给活动的对象添加标记
- 清除阶段:清除阶段就是清除掉没有标记(不活动)的对象。
在开发的过程中,如果我们想让垃圾回收器回收一个对象,我们可以将这个对象的引用设置为null,这个时候就垃圾回收器就可以回收这个对象了,但是如果将一个对象设置为另外一个对象的属性或者值,这个时候在将前面那个对象设置为null,这样前面那个对象任然不可以被释放。
var a = {}; var arr = [a]; a = null; console.log(arr) // [{}]
如果作为 Map 的键喃?
var a = {}; var map = new Map(); map.set(a, '三分钟学前端') a = null; console.log(map.keys()) // MapIterator {{}} console.log(map.values()) // MapIterator {"三分钟学前端"}
如果想让 a 置为 null 时,该对象被回收,该怎么做?
二、WeakMap和Map
WeakMap和Map类似,都是一个存储对象的类型,但是也有一些不同:
- Map的键可以是任何的类型,但是weakMap的键必须是对象类型;
- Map是可以被迭代的,而weakMap是不可以被迭代的。
- Map中键的引用是地址,如果两个地址不一样,就是不同的数据,而WeakMap对键的引用是“弱”引用,他所引用的键是可以被回收的。
每个键对自己所引用对象的引用都是弱引用,在没有其他引用和该键引用同一对象,这个对象将会被垃圾回收(相应的key则变成无效的),所以,WeakMap 的 key 是不可枚举的。