JavaScript垃圾回收器是如何工作的,以及何时工作?

4
我读了一些有关如MDN上的这篇文章,我明白了JavaScript中的GC是如何运行的。
但我仍不理解以下事项:
a) 垃圾回收器何时启动(它是在一定间隔后被调用还是必须满足某些条件)?
b) 谁负责垃圾回收(它是JavaScript引擎或浏览器/Node的一部分)?
c) 运行在主线程还是独立线程上?
d) 以下哪一个具有更高的峰值内存使用率?
// first-case
// variables will be unreachable after each cycle

(function() {
  for (let i = 0; i < 10000; i++) {
    let name = 'this is name' + i;
    let index = i;
  }
})()

// second-case
// creating variable once

(function() {
  let i, name, index;

  for (i = 0; i < 10000; i++) {
    name = 'this is name' + i;
    index = i;
  }
})()
1个回答

9
我是一名V8开发者。简单来说,情况比较复杂。特别是不同的JavaScript引擎以及同一引擎的不同版本会有所不同。
针对您具体的问题:
a) 垃圾回收器何时启动(在一定时间间隔后调用还是必须满足某些条件)?
答:取决于情况。现代垃圾回收器通常是分代的:它们有一个相对较小的“年轻代”,每当它被填满时就会进行垃圾回收。此外,它们还有一个更大的“老年代”,在其中它们通常通过许多小步骤来完成工作,以便不会中断执行太长时间。触发这样的小步骤的一种常见方式是当自上次步骤以来已分配了N个字节(或对象)时。另一种方式,特别是在现代选项卡式浏览器中,是在选项卡处于非活动或后台状态时触发GC活动。除了这两种方法之外,可能还有其他触发器。
b) 谁负责垃圾回收(它是JavaScript引擎或浏览器/Node的一部分)?
答:垃圾回收器是JavaScript引擎的一部分。也就是说,它必须与相应的嵌入程序进行某些交互,以处理与JavaScript对象某种方式相关联的嵌入程序管理的对象(例如DOM节点)的生命周期。 c) 运行在主线程还是单独的线程上? 取决于具体实现,通常两者都有:一些工作在后台执行(在一个或多个线程中),有些步骤更有效率地在主线程中执行。 d) 以下哪个占用峰值内存更高? 这两个代码片段的峰值内存使用可能相同:它们都不允许多个迭代分配的对象同时可达。

编辑:如果您想了解有关V8最近进行的与GC相关的工作的更多信息,您可以在此处找到一系列博客文章:https://v8.dev/blog/tags/memory


哪一个代码片段的峰值内存使用率更高?第一个代码片段不会有更高的峰值内存使用率(尽管稍后会被GC收集)吗? - manjuv
@manjuv 没有理由表明这两个片段中的任何一个比另一个具有更高的峰值内存使用率。 - jmrk

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接