JavaScript 垃圾收集器何时以及如何工作

When and How JavaScript garbage collector works

我确实读过几篇文章,比如 this on MDN and this one 我了解了 GC 在 JavaScript

中是如何发生的

我还是不明白

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

b) 谁负责垃圾收集(它是 JavaScript 引擎或 browser/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;
  }
})()

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

解决您的具体问题:

a) When does Garbage collector kicks in ( it gets called after some interval or some conditions have to met) ?

视情况而定。可能两者都有。现代垃圾收集器通常是分代的:它们有一个相对较小的 "young generation",只要它满了就会被收集。此外,他们有一个更大的 "old generation",他们通常在许多小步骤中完成他们的工作,以便永远不会中断执行太久。触发如此小步骤的一种常见方式是自上一步以来已分配 N 个字节(或对象)。另一种方法,尤其是在现代标签浏览器中,是在标签处于非活动状态或处于后台时触发 GC activity。除了这两个,很可能还有其他触发器。

b) Who is responsible for Garbage collection ( it's part of JavaScript engine or browser/Node ) ?

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

c) runs on main thread or separate thread ?

视情况而定。在现代实现中,通常两者兼而有之:一些工作发生在后台(在一个或多个线程中),一些步骤在主线程上执行效率更高。

d) which one of the following have higher peak memory usage ?

这两个片段(可能)具有相同的内存使用峰值:它们都不允许同时访问由多次迭代分配的对象。


编辑:如果您想了解更多关于 V8 最近所做的 GC 相关工作,您可以在此处找到一系列博文:https://v8.dev/blog/tags/memory