JavaScript中的垃圾回收是自动进行的,在平常开发中我们可能并不在意,但是深入理解JavaScript中的垃圾回收却是必要的;
JavaScript 中主要的内存管理概念是 可达性,简而言之就是储存在内存中无法被释放的值;
先了解一下什么是根的概念?
比方说:
- 当前函数的局部变量和参数。
- 嵌套调用时,当前调用链上所有函数的变量与参数。
- 全局变量。
- (还有一些内部的)
这些值被称作 根(roots)。
如果一个值可以通过引用或引用链从根访问任何其他值,则认为该值是可达的。
比如说:
<pre style="color: rgb(0, 0, 0); font-family: "Courier New"; font-size: 12px; margin: 5px 8px; padding: 5px;">var something = {
key:"value" }</pre>
对象字面量{key:"value"} 被 something这个变量引用着,则说明这个根是可达的,不会被进行垃圾回收;
接下来:
<pre style="color: rgb(0, 0, 0); font-family: "Courier New"; font-size: 12px; margin: 5px 8px; padding: 5px;">something = null;</pre>
切断了 something 与 这个对象字面量之间的连接,这个对象字面量就变成 不可达,然后等待它的就是无情的垃圾回收;
更进一步:
<pre style="color: rgb(0, 0, 0); font-family: "Courier New"; font-size: 12px; margin: 5px 8px; padding: 5px;">var marry = function(man,woman) {
man.wife = woman;
woman.husband = man; return {
father:man,
mother:woman
}
} var family = marry({name:'man'},{name:'woman'});</pre>
从上面代码中可以看到多个对象之间相互引用,到目前为止,这些对象都是可达的;
从源头切断:
<pre style="color: rgb(0, 0, 0); font-family: "Courier New"; font-size: 12px; margin: 5px 8px; padding: 5px;">family = null;</pre>
虽然 man 和 woman 还保持着相互引用,但是我们切断family与marry函数返回对象之间的联系,使得 该函数返回的对象成为一座孤岛;
那么,等待它的将会是无情的垃圾回收机制;
垃圾回收算法简述
JavaScript引擎的垃圾回收基本算法是"mark and sweep";直白的来说就是标记并清理;
- JavaScript引擎找到所有的“根”并mark它们
- 然后遍历并mark来自它们的所有引用,所有遍历到的对象都会被mark
- 直到所有可达的引用都被标记到
- 没有被标记的对象都会被删除
博客园地址
推荐阅读:《现代JavaScript教程》- 垃圾回收
2021-02-04