[译] 通过垃圾回收机制理解 JavaScript 内存管理「建议收藏」

[译] 通过垃圾回收机制理解 JavaScript 内存管理「建议收藏」内存管理的主要目标是在需要的时候为系统动态地分配内存,然后释放那些不再使用的对象的内存。像 C 和 C++ 这样的语言有基本的内存分配函数,如 malloc(),而一些高级语言计算机体系结构(如 JavaScript)包含垃圾回收器来完成这项工作。它跟踪内存分配并识别这些分配的…

[译] 通过垃圾回收机制理解 JavaScript 内存管理「建议收藏」

照片来自 Unsplash 上的 Dlanor S

内存管理的主要目标是在需要的时候为系统动态地分配内存,然后释放那些不再使用的对象的内存。像 C 和 C++ 这样的语言有基本的内存分配函数,如 malloc(),而一些高级语言计算机体系结构(如 JavaScript)包含垃圾回收器来完成这项工作。它跟踪内存分配并识别这些分配的内存是否不再使用,如果是就自动释放。但是这种算法不能完全决定内存是否仍被需要。因此,对于程序员来说,理解并决定一段特定的代码是否需要内存是非常重要的。让我们了解一下 JavaScript 中的垃圾收集是如何工作的:

垃圾回收

JavaScript 引擎的垃圾回收器基本上是寻找内存中被删除的无法访问的对象。这里我想解释两种垃圾回收算法,如下所示:

  • 引用计数垃圾回收
  • 标记清除算法

引用计数垃圾回收

这是一个简单的垃圾回收算法。这个算法寻找那些没有被引用的对象。如果一个对象没有被引用,那么该对象就可以被垃圾回收。

var obj1 = {
    property1: {
         subproperty1: 20
     }
};

如上例所示,让我们创建一个对象以理解这个算法。这里 obj1 引用了一个对象,其中的 property1 属性也引用了一个对象。由于 obj1 具有对象的引用,因此这个对象不会被垃圾回收。

var obj2 = obj1;

obj1 = "some random text"

现在,obj2 也引用了被 obj1 引用的同一个对象,但后来 obj1 被更新为了 "some random text",这导致 obj2 具有对该对象的唯一引用。

var obj_property1 = obj2.property1;

现在 obj_property1 指向 obj2.property1,它引用了一个对象。因此该对象有两个引用,如下所示:

  1. 作为 obj2 的属性
  2. 在变量 obj_property1
obj2 = "some random text"

通过更新为 "some random text" 来取消 obj2 对对象的引用。因此,之前的这个对象似乎没有被引用了,所以它可以被垃圾回收。但是,由于 obj_property1 具有 obj2.property1 的引用,因此它不会被垃圾回收。

obj_property1 = null;

当我们把 obj_property1 引用删除,现在最初 obj1 指向的对象没有引用了。所以现在它可以被垃圾回收。

这个算法在哪里失败了?

function example() {
     var obj1 = {
         property1 : {
              subproperty1: 20
         }
     };
     var obj2 = obj1.property1;
     obj2.property1 = obj1;
     return 'some random text'
}

example();

这里引用计数算法在函数调用之后不会从内存中删除 obj1obj2 ,因为两个对象都是相互引用的。


标记清除算法

这个算法查找从根开始无法访问的对象,这个根是 JavaScript 的全局对象。该算法克服了引用计数算法的局限性。没有引用的对象是不可访问的,但是反过来就不一定了。

var obj1 = {
     property1: 35
}

[译] 通过垃圾回收机制理解 JavaScript 内存管理「建议收藏」

如上所示,我们可以看到创建的对象 obj1 如何从 ROOT 中访问到的。

obj1 = null

[译] 通过垃圾回收机制理解 JavaScript 内存管理「建议收藏」

现在,当我们将 obj1 的值设置为 null 时,该对象从根开始无法被访问,因此它可以被垃圾回收。

该算法从根开始,遍历所有其他对象,同时标记它们。它进一步遍历被遍历的对象并标记它们。这个过程将被重复直到所有已被遍历的节点没有任何子节点和可遍历的路径。现在垃圾回收器会忽略所有可访问对象,因为它们在遍历时被标记。因此,所有未标记的对象显然都是从根节点开始无法访问的,这意味着它们可以被垃圾回收,稍后通过删除这些对象释放内存。让我们通过下面的例子来试着理解一下:

[译] 通过垃圾回收机制理解 JavaScript 内存管理「建议收藏」

如上所示,这就是对象结构的样子。我们可以注意到无法从根开始访问的对象,但是让我们尝试了解在这种情况下标记清除算法是如何工作的。

[译] 通过垃圾回收机制理解 JavaScript 内存管理「建议收藏」

算法从根开始标记遍历到的对象。上面的图片中,我们可以注意到在对象上标记的绿色圆圈。这样它就可以将对象标识为可从根开始可以访问到。

[译] 通过垃圾回收机制理解 JavaScript 内存管理「建议收藏」

未被标记的对象是无法从根开始被访问到的。因此它们可以被垃圾回收。

局限性

对象必须显式地设置为不可访问。

自 2012 年以来,JavaScript 引擎已经使用此算法来代替引用计数垃圾回收。

谢谢阅读。


进一步阅读:

如果发现译文存在错误或其他需要改进的地方,欢迎到 掘金翻译计划 对译文进行修改并 PR,也可获得相应奖励积分。文章开头的 本文永久链接 即为本文在 GitHub 上的 MarkDown 链接。


掘金翻译计划 是一个翻译优质互联网技术文章的社区,文章来源为 掘金 上的英文分享文章。内容覆盖 AndroidiOS前端后端区块链产品设计人工智能等领域,想要查看更多优质译文请持续关注 掘金翻译计划官方微博知乎专栏

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
转载请注明出处: https://daima100.com/13802.html

(0)

相关推荐

  • 接口调用异常怎么解决_sap webservice

    接口调用异常怎么解决_sap webservice背景 公司的一个项目,需要记录某个接口的访问pv、uv,并且不能丢失明细数据,需要记录【用户,调用接口,调用详情,调用时间,调用次数】 之前使用MySQL记录,每来一条记录一条,例如: insert

    2023-05-22
    138
  • MongoDB学习(一) — 入门安装「建议收藏」

    MongoDB学习(一) — 入门安装「建议收藏」1、简介 MongoDB 是由 C++语言编写的,是一个基于分布式文件储存的开源数据库系统。 在高负载的情况下,添加更多的节点,可以保证服务器性能。 MongoDB 旨在为WEB应用提供可扩展的高性…

    2023-03-10
    146
  • 深入分析Mimikatz:SSP

    深入分析Mimikatz:SSP在前一篇文章中,我们开始深入分析Mimikatz。我们的想法很简单,就是想澄清Mimikatz内部的工作原理,以便开发自定义和有针对性的payload。微软引入了一些安全控制机制(如Credential Guard),避免攻击者转储凭据信息。在本文中,我们将回顾一下绕过这种机制…

    2023-08-02
    148
  • switch case_switchcase函数

    switch case_switchcase函数语言的底层就是算法,所以switch-case的底层也是算法: 数组和二分查找。 switch-case是一个条件语句,也就是说:

    2023-07-24
    140
  • net start npf_MySQL启动

    net start npf_MySQL启动造成这种情况的原因有很多,如果直接百度错误信息的话,不一定能很快解决问题,所以,出现这种情况,我们可以使用 mysqld console 命令来查看报错信息,然后根据报错信息来百度,这样就很快定位到问

    2023-01-23
    171
  • 【计理01组05号】MySql基础课程【2.0】[通俗易懂]

    【计理01组05号】MySql基础课程【2.0】[通俗易懂]博客推行版本更新,成果积累制度,已经写过的博客还会再次更新,不断地琢磨,高质量高数量都是要追求的,工匠精神是学习必不可少的精神。因此,大家有何建议欢迎在评论区踊跃发言,你们的支持是我最大的动力,你们敢

    2023-05-08
    135
  • 索引的树结构[亲测有效]

    索引的树结构[亲测有效]查找结构的进化 二分查找 二叉树 二叉平衡树 B-TREE :二叉平衡树的基础上,使加载一次节点,可以加载更多路径数据,同时把查询范围缩减到更小 缺点:业务数据的大小可能远远超过了索引数据的大小,每次

    2023-05-27
    133
  • 艺术喵 2 年前端面试心路历程(字节跳动、YY、虎牙、BIGO)| 掘金技术征文

    艺术喵 2 年前端面试心路历程(字节跳动、YY、虎牙、BIGO)| 掘金技术征文本文将先从个人背景讲起,然后谈谈在字节跳动、虎牙、YY 以及 BIGO 的面试经过,最后讲一下关于计算机基础、算法与数据结构、JavaScript 等方面的学习经验,以及聊聊个人学习经验。 2016 年到 2017 年在网易互动娱乐从事游戏品牌宣传后期美术、CC 语音(现 CC…

    2023-08-21
    124

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注