JS 查漏补缺之内存管理

对于开发者来说,JavaScript 的内存管理是自动的、无形的。我们创建的原始值、对象、函数……这一切都会占用内存。

JavaScript 中主要的内存管理概念是 可达性。

简而言之,“可达”值是那些以某种方式可访问或可用的值。它们一定是存储在内存中的。

  1. 这里列出固有的可达值的基本集合,这些值明显不能被释放。

    比方说:

    • 当前函数的局部变量和参数。
    • 嵌套调用时,当前调用链上所有函数的变量与参数。
    • 全局变量。
    • (还有一些内部的)

    这些值被称作 根(roots)。

  2. 如果一个值可以通过引用或引用链从根访问任何其他值,则认为该值是可达的。

    比方说,如果全局变量中有一个对象,并且该对象有一个属性引用了另一个对象,则 该 对象被认为是可达的。而且它引用的内容也是可达的。下面是详细的例子。

在 JavaScript 引擎中有一个被称作垃圾回收器的东西在后台执行。它监控着所有对象的状态,并删除掉那些已经不可达的。  

这里是一个最简单的例子:

// user 具有对这个对象的引用
let user = {
  name: "John"
};

如果 user 的值被重写了,这个引用就没了:

user = null;

 现在 John 变成不可达的了。因为没有引用了,就不能访问到它了。垃圾回收器会认为它是垃圾数据并进行回收,然后释放内存。  

我们把 user 的引用复制给 admin

// user 具有对这个对象的引用
let user = {
  name: "John"
};

let admin = user;

现在如果执行刚刚的那个操作:

user = null;

 ……然后对象仍然可以被通过 admin 这个全局变量访问到,所以对象还在内存中。如果我们又重写了 admin,对象才会被删除  

对外引用不重要,只有传入引用才可以使对象可达。意思是一个对象引用另一个对象、但没有对此对象的引用,此对象不可达

几个对象相互引用,但外部没有对其任意对象的引用,这些对象也可能是不可达的,并被从内存中删除。   

垃圾回收的基本算法被称为 “mark-and-sweep”。

定期执行以下“垃圾回收”步骤:

  • 垃圾收集器找到所有的根,并“标记”(记住)它们。
  • 然后它遍历并“标记”来自它们的所有引用。
  • 然后它遍历标记的对象并标记 它们的 引用。所有被遍历到的对象都会被记住,以免将来再次遍历到同一个对象。
  • ……如此操作,直到所有可达的(从根部)引用都被访问到。
  • 没有被标记的对象都会被删除。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值