垃圾回收器是一把十足的双刃剑。好处是简化程序的内存管理,内存管理无需程序员来操作,由此也减少了长时间运转的程序的内存泄漏。然而无法预期的停顿,影响了交互体验。本文从 V8 (node.js runtime) 的角度分析垃圾回收策略。
暂时没弄懂v8的,有时间再研究
下面的是js垃圾回收
内存的生命周期:
- 分配你所需要的内存
- 使用分配到的内存(读、写)
- 不需要时将其释放归还
所以,我们只要知道js引擎怎么判断内存变量不再需要,就知道js是在什么时候回收内存变量了。
我们先来说一种古老的垃圾回收机制:
引用计数垃圾收集
这是最简单的垃圾收集算法。此算法把“对象是否不再需要”简化定义为“对象有没有其他对象引用到它”。如果没有引用指向该对象(零引用),对象将被垃圾回收机制回收。
我们看一段代码来分析:
1 // 两个对象被创建,一个作为另一个的属性被引用,另一个被分配给变量o 2 // 很显然,没有一个可以被垃圾收集 3 var o = { 4 a: { 5 b:2 6 } 7 }; 8 9 // o2变量是第二个对“这个对象”的引用 10 var o2 = o; 11 12 // 现在,“这个对象”的原始引用o被o2替换了 13 o = 1; 14 15 // 引用“这个对象”的a属性 16 // 现在,“这个对象”有两个引用了,一个是o2,一个是oa 17 var oa = o2.a; 18 19 // 最初的对象现在已经是零引用了 20 // 他可以被垃圾回收了 21 // 然而它的属性a的对象还在被oa引用,所以还不能回收 22 o2 = "yo"; 23 oa = null; 24 // a属性的那个对象现在也是零引用了 25 // 它可以被垃圾回收了
引用计数垃圾收集有一个很大的缺陷:无法处理循环引用
但是无法处理下列代码:
function f(){ var o = {}; var o2 = {}; // o 引用 o2 o.a = o2; // o2 引用 o o2.a = o; } f();
标记-清除垃圾收集
这个算法把“对象是否不再需要”简化定义为“对象是否可以获得”。
这个算法假定设置一个叫做根(root)的对象(在Javascript里,根是全局对象)。定期的,垃圾回收器将从根开始,找所有从根开始引用的对象,然后找这些对象引用的对象……从根开始,垃圾回收器将找到所有可以获得的对象和所有不能获得的对象。