Javascript 垃圾回收

Javascript 垃圾回收

内存管理Javascript是自动完成的,对用户来说是透明的。我们创建原始类型、对象、函数等,所有这些都需要占用内存。当一些对象不再被需要时,Javascript引擎是如何发现并清除?

能达性(Reachability)

Javascript内存管理主要概念是能达性。简单说,“能达”是那些可被访问或使用值,他们需保证存储在内存中。
1、继承可达值,他们显然不能被删除。

  • 当前函数中局部变量和参数
  • 在当前嵌套调用链的其他函数使用的变量或参数
  • 全局变量

2、从一个根引用或引用链可到达的值。
如一个对象有内部变量被另一个对象的属性引用,则该对象是能到达的。

Javascript引擎有后台进程称为垃圾回收,它监控所有对象并删除那些不可到达的对象。

示例1

// user has a reference to the object
let user = {
  name: "John"
};

user = null;

这里全局对象user引用对象{name:”John”},如果user被重写,则引用丢失,现在对象{name:”John”}变得不可达,没有办法访问,没有引用指向它,垃圾回收程序将丢弃数据释放内存。

// user has a reference to the object
let user = {
  name: "John"
};

let admin = user;

user = null;

这段代码,有两个引用指向对象,删除一个,仍然有admin指向对象,因此对象不会被回收。

相互链接对象

看下面一个复杂的示例

function marry(man, woman) {
  woman.husband = man;
  man.wife = woman;

  return {
    father: man,
    mother: woman
  }
}

let family = marry({
  name: "John"
}, {
  name: "Ann"
});

函数marry缔结两个对象,两个对象之间相互引用,然后返回一个新对象包含他们一起,内存结构如下:

现在所有对象都可到达,现在删除变量。

delete family.father;
delete family.mother.husband;


删除其中任何一个都不能Johe对象(简写)不可到达,但现在删除两个,我们能看到John对象不再有输入引用。

向外引用不重要,只有输入引用会让对象可达。所以John对象现在不能到达,将被垃圾回收,其所有数据也不能被访问。回收后内存结构如下:

孤岛

相互链接的孤岛对象可能变成不可到达,同样也会被回收,下面代码示例:

family = null;

内存结构变成:

显然John对象和Ann对象相互引用,互为输入引用,但这是不够的,family对象已经从根断开,不再有引用指向孤岛对象,所有整个孤岛将被回收。内部算法这里不再详述。

总结

  • 垃圾回收是自动执行的,我们无法阻止。
  • 当对象是可到达时,保留在内存中。
  • 被引用与可到达不同(从一个根),如相互引用对象整体不能到达。

现代引擎如V8实现了垃圾回收的高级算法,优化性能,快速准确回收。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值