了解JavaScript中的垃圾回收机制

了解JavaScript中的垃圾回收机制

推荐教程:《JavaScript视频教程》

最近看到一些面试的回顾,不少有被面试官问到谈谈JS 垃圾回收机制,说实话,面试官会问这个问题,说明他最近看到一些关于 JS 垃圾回收机制的相关的文章,为了 B 格,就会顺带的问问。

最近看到一篇讲 JS 垃圾回收的国外文章,觉得讲得明白,所以就翻译过来了,希望对你们有所帮助。

垃圾回收

JavaScript 中的内存管理是自动执行的,而且是不可见的。我们创建基本类型、对象、函数……所有这些都需要内存。

立即学习“Java免费学习笔记(深入)”;

当不再需要某样东西时会发生什么? JavaScript 引擎是如何发现并清理它?

可达性

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

简单地说,“可达性” 值就是那些以某种方式可访问或可用的值,它们被保证存储在内存中。

1. 有一组基本的固有可达值,由于显而易见的原因无法删除。例如:

本地函数的局部变量和参数

当前嵌套调用链上的其他函数的变量和参数

全局变量

还有一些其他的,内部的

这些值称为根。

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

例如,如果局部变量中有对象,并且该对象具有引用另一个对象的属性,则该对象被视为可达性, 它引用的那些也是可以访问的,详细的例子如下。

JavaScript 引擎中有一个后台进程称为垃圾回收器,它监视所有对象,并删除那些不可访问的对象。

一个简单的例子

下面是最简单的例子:

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

登录后复制

1.png

这里箭头表示一个对象引用。全局变量“user”引用对象 {name:“John”} (为了简洁起见,我们将其命名为John)。John 的 “name” 属性存储一个基本类型,因此它被绘制在对象中。

如果 user 的值被覆盖,则引用丢失:

user = null;

登录后复制登录后复制

2.png

现在 John 变成不可达的状态,没有办法访问它,没有对它的引用。垃圾回收器将丢弃 John 数据并释放内存。

两个引用

现在让我们假设我们将引用从 user 复制到 admin:

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

登录后复制

3.png

现在如果我们做同样的事情:

user = null;

登录后复制登录后复制

该对象仍然可以通过 admin 全局变量访问,所以它在内存中。如果我们也覆盖admin,那么它可以被释放。

相互关联的对象

现在来看一个更复杂的例子, family 对象:

function marry (man, woman) {  woman.husban = man;  man.wife = woman;  return {    father: man,    mother: woman  }}let family = marry({  name: "John"}, {  name: "Ann"})

登录后复制

函数 marry 通过给两个对象彼此提供引用来“联姻”它们,并返回一个包含两个对象的新对象。

产生的内存结构:

4.png

到目前为止,所有对象都是可访问的。

现在让我们删除两个引用:

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

登录后复制

5.png

仅仅删除这两个引用中的一个是不够的,因为所有对象仍然是可访问的。

但是如果我们把这两个都删除,那么我们可以看到 John 不再有传入的引用:

6.png

输出引用无关紧要。只有传入的对象才能使对象可访问,因此,John 现在是不可访问的,并将从内存中删除所有不可访问的数据。

垃圾回收之后:

7.png

无法访问的数据块

有可能整个相互连接的对象变得不可访问并从内存中删除。

源对象与上面的相同。然后:

family = null;

登录后复制

内存中的图片变成:

8.png

这个例子说明了可达性的概念是多么重要。

很明显,John和Ann仍然链接在一起,都有传入的引用。但这还不够。

“family”对象已经从根上断开了链接,不再有对它的引用,因此下面的整个块变得不可到达,并将被删除。

内部算法

基本的垃圾回收算法称为“标记-清除”,定期执行以下“垃圾回收”步骤:

垃圾回收器获取根并“标记”(记住)它们。

然后它访问并“标记”所有来自它们的引用。

然后它访问标记的对象并标记它们的引用。所有被访问的对象都被记住,以便以后不再访问同一个对象两次。

以此类推,直到有未访问的引用(可以从根访问)为止。

除标记的对象外,所有对象都被删除。

例如,对象结构如下:

9.png

我们可以清楚地看到右边有一个“不可到达的块”。现在让我们看看“标记并清除”垃圾回收器如何处理它。

第一步标记根

10.png

然后标记他们的引用

11.png

以及子孙代的引用:

12.png

现在进程中不能访问的对象被认为是不可访问的,将被删除:

13.png

这就是垃圾收集的工作原理。JavaScript引擎应用了许多优化,使其运行得更快,并且不影响执行。

一些优化:

分代回收——对象分为两组:“新对象”和“旧对象”。许多对象出现,完成它们的工作并迅速结 ,它们很快就会被清理干净。那些活得足够久的对象,会变“老”,并且很少接受检查。

增量回收——如果有很多对象,并且我们试图一次遍历并标记整个对象集,那么可能会花费一些时间,并在执行中会有一定的延迟。因此,引擎试图将垃圾回收分解为多个部分。然后,各个部分分别执行。这需要额外的标记来跟踪变化,这样有很多微小的延迟,而不是很大的延迟。

空闲时间收集——垃圾回收器只在 CPU 空闲时运行,以减少对执行的可能影响。

面试怎么回答

1)问什么是垃圾

一般来说没有被引用的对象就是垃圾,就是要被清除, 有个例外如果几个对象引用形成一个环,互相引用,但根访问不到它们,这几个对象也是垃圾,也要被清除。

2)如何检垃圾

一种算法是标记 标记-清除 算法,还想说出不同的算法可以参考这里。

更深入一些的讲解 V8 之旅: 垃圾回收器

更多编程相关知识,请访问:编程入门!!

以上就是了解JavaScript中的垃圾回收机制的详细内容,更多请关注【创想鸟】其它相关文章!

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

发布者:PHP中文网,转转请注明出处:https://www.chuangxiangniao.com/p/2724700.html

(0)
上一篇 2025年3月7日 23:16:26
下一篇 2025年2月22日 19:51:24

AD推荐 黄金广告位招租... 更多推荐

相关推荐

  • 详细了解JavaScript中的延迟加载

    在这篇文章中,我们将看看延迟加载在web上是如何工作的。我们将介绍本地延迟加载API——延迟加载是如何实现的,延迟加载的重要性和优点,最后是一个简单的延迟加载web内容用例。 理解延迟加载API及其工作方式将帮助已经使用实现这些技术的库和框…

    2025年3月7日
    200
  • 详解JS中的执行上下文和执行栈

    如果你是一名 JavaScript 开发者,或者想要成为一名 JavaScript 开发者,那么你必须知道 JavaScript 程序内部的执行机制。执行上下文和执行栈是 JavaScript 中关键概念之一,是 JavaScript 难点…

    2025年3月7日 编程技术
    200
  • 深入了解JavaScript 缓存

    随着我们的应用程序的不断增长并开始进行复杂的计算时,对速度的需求越来越高,所以流程的优化变得必不可少。 当我们忽略这个问题时,我们最终的程序需要花费大量时间并在执行期间消耗大量的系统资源。 推荐教程:《JavaScript视频教程》 缓存是…

    2025年3月7日 编程技术
    200
  • js中isNaN和Number.isNaN的区别是什么

    区别:Number.isNaN不存在类型转换的行为,而isNaN会尝试将参数转换成Number类型。isNaN只是判断传入的参数是否能转换成数字,并不是严格的判断是否等于NaN;而Number.isNaN判断传入的参数是否严格的等于NaN。…

    2025年3月7日
    200
  • react可以做什么?

    react是一个JavaScript库,主要用于构建UI,可用于构建“可预期的”和“声明式的”Web用户界面;React能够构建那些数据会随时间改变的大型应用,并且能够提高开发效率。 React 起源于 Facebook 的内部项目,因为该…

    2025年3月7日
    200
  • JavaScript常见几种的内存泄漏

    javascript栏目教程介绍常见的内存泄漏。 前言1 介绍2 内存泄露的主要原因3 常见的内存泄露3.1 全局变量3.2 计时器3.3 多处引用3.4 闭包4 Chrome内存分析工具资料 前言 在阅读这篇博客之前,你或许需要具备一些J…

    2025年3月7日
    200
  • JavaScript算法之归并排序算法(详解)

    在本文中,我们学习 Merge Sort 背后的逻辑,并用 JavaScript 实现。最后,在空间和时间复杂度方面将归并排序与其他算法进行比较。 归并排序背后的逻辑 归并排序使用分而治之的概念对给定的元素列表进行排序。它将问题分解为较小的…

    2025年3月7日
    100
  • 避免在JS脚本中过多使用 if 语句,6种代替 if 的方法介绍

    推荐教程:《JavaScript视频教程》 最近在重构代码时,我发现早期的代码使用太多的 if 语句,其程度是我从未见过的。这就是为什么我认为分享这些简单的技巧是非常重要的,这些技巧可以帮助我们避免过多的使用 if 语句。 接下来会介绍6种…

    2025年3月7日
    200
  • JavaScript如何禁止刷新页面

    JavaScript禁止刷新页面的方法:1、禁用F5刷新,代码为【if (event.keyCode == 116) 】;2、禁止右键弹出菜单,代码为【document.oncontextmenu = function ()】。 本教程操作…

    2025年3月7日
    200
  • javascript介绍前端安全知多少

    今天javascript栏目介绍前端安全。 前言 Hello,AV8D~今天我们要分享的主题是前端Web安全。web安全的重要性不言而喻,是所有互联网企业都绕不开的话题。 在web前端领域,尽管浏览器已经在系统层面帮我们做了诸多的隔离和保护…

    2025年3月7日 编程技术
    200

发表回复

登录后才能评论