JavaScript垃圾收集器的工作时间和方式

时间:2019-09-25 14:18:14

标签: javascript garbage-collection v8 spidermonkey

我确实读过几篇诸如this on MDNthis one之类的文章,我了解到GC在JavaScript中是如何发生的

我还是不明白

a)垃圾收集器何时启动(在一定间隔或必须满足某些条件后调用)?

b)谁负责垃圾收集(它是JavaScript引擎或浏览器/ Node的一部分)?

c)运行在主线程还是单独的线程上?

d)以下哪一项具有更高的峰值内存使用率?

// (i) 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;
  }
})()
// (ii) second-case

(function() {
  let i, name, index; // creating variable once

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

1 个答案:

答案 0 :(得分:3)

V8开发人员在这里。简短的答案是:很复杂。特别是,不同的JavaScript引擎和同一引擎的不同版本会做不同的事情。

要解决您的特定问题:

  

a)垃圾收集器何时启动(在一定间隔或必须满足某些条件后调用)?

取决于。可能两者都有。现代垃圾收集器通常是代代相传的:它们具有相对较小的“年轻代”,只要装满就可以收集。此外,他们还有一个更大的“老一代”,他们通常会在许多小的步骤中完成工作,以免中断执行时间太长。触发如此小的步骤的一种常见方法是自上一步以来已分配了N个字节(或对象)。另一种方法(尤其是在现代选项卡式浏览器中)是在选项卡处于非活动状态或在后台时触发GC活动。除了这两个之外,可能还有其他触发器。

  

b)谁负责垃圾收集(它是JavaScript引擎或浏览器/ Node的一部分)?

垃圾收集器是JavaScript引擎的一部分。也就是说,它必须与相应的嵌入程序进行某种交互才能处理其生命周期以某种方式与JavaScript对象相关联的嵌入程序管理的对象(例如DOM节点)。

  

c)运行在主线程还是单独的线程上?

取决于。在一种现代的实现中,通常是两种情况:在后台(一个或多个线程中)进行某些工作,在主线程上执行某些步骤更有效。

  

d)以下哪一项具有更高的峰值内存使用率?

这两个代码片段(可能)具有相同的峰值内存使用率:它们都不曾让一次以上迭代分配的对象可以同时到达。


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