JavaScript 中的垃圾
- JavaScript 中的内存管理是自动的
- 对象不再被引用时是垃圾
- 对象不能从根本上访问到时是垃圾
每当我们创建一个对象、数组或者函数的时候会自动的分配相应的内存空间,后面执行的过程中,通过引用关系无法找到某些对象的时候,这些个对象就会被看作是垃圾。但是由于代码当中不合适的语法或者是结构性的错误,让我们没有办法找到对应的对象,这种对象也是垃圾
JavaScript 中的可达对象
- 可以访问到的对象就是可达对象(引用、作用域链)
- 可达的标注就是从根触发是否能够被找到
- JavaScript 中的根就可以理解为全局变量对象
JavaScript 中的垃圾回收其实就是找到垃圾,JavaScript执行引擎来执行空间的释放和回收,这里就用到了引用和可达对象
JavaScript 中的引用和可达
// reference
let obj = {name: 'deyang'}
let ali = obj
obj = null
{name: 'deyang'} 的对象空间 被 obj 引用了。站在全局的执行上下文下,当前的 obj 是可以从根上被找到的,所以 obj 也是可达的,间接意味着 deyang 的对象空间其实是可达的。从新定义变量 ali = obj,可以认为 deyang 的对象空间多了一层引用,这里触及到引用数值变化的,涉及到GC算法。最后把 obj 赋值为 null。本来 deyang 的对象空间是有两个引用的,但是随着 obj = null,obj 到 deyang 对象空间的引用其实是被断掉了,那么当前的 deyang 对象空间是否还是可达的呢?显然是的,因为 ali 还有有一份引用可达
function objGroup(obj1, obj2) {
obj1.next = obj2
obj2.prev = obj1
return {
o1: obj1,
o2: obj2
}
}
let obj = objGroup({name: 'obj1'}, {name: 'obj2'})
console.log(obj)
定义一个 objGroup 函数接受两个参数obj1, obj2,内部中,两个对象有个属性互相指引,最后通过return 关键字返回结果。最后进行函数调用输出结果
可达对象图示
首先从全局的根出发,这边可以找到可达对象 obj ,它是通过函数调用指向了一个引用空间,它的里面就是我们看到的o1 和 o2。 o1 和 o2 里面又通过相应的属性,指向了 obj1 的空间 和 obj2 的空间,所以 o1 和 o2通过next 和 prev 互相引用空间。那么现在代码中所出现的对象,都可以从根上来进行查找,无论是多么的麻烦。
如果我们用delet 语句把 obj 中 o1对 obj1 引用 以及 o2 对 obj1 的引用,都删除掉。
delete obj.o1
delete obj.o2.prev
那现在我们没有什么方法来找到 obj1 的引用空间的,所有能找到 obj1 的引用线条都被删除了。在这里它就会被认为是一个垃圾。最后引擎找到它并对它进行回收