这个函数可以被垃圾收集吗?

Can this function be garbage-collected?

考虑一下这块蛋糕...嗯,代码:

'use strict'

function doWork () {
  return new Promise(function (resolve, reject) {
    // work work work...
    // Done! But... where's the resolve() ???
  })
}

doWork().then(function doMoreWork () {
  // Some more work to do...
})

一旦 Promise 的构造函数中的函数完成...

  1. Promise 对象是可回收垃圾吗?
  2. doMoreWork() 垃圾可以收集吗?

我的猜测是 doMoreWork() 不能直接进行 GC,因为 Promise 保留对它的引用,但是一旦 promise 的主体完成并且 returns 执行上下文到上层(?)范围,堆栈展开(因为这里没有更多的语句要执行)并且 Promise 变得不可访问,因此是垃圾回收的。

你能确认我对这个话题的理解是正确的吗?

我如何凭经验观察这种行为? 换句话说,我如何监控哪些对象在何时被 GC 处理?我纯粹在 Node.js 中开发,如果这有什么不同的话。

  1. 如果没有指向它的引用,Promise 对象是可收集的。 如果使用 doWork().then(...),则会创建一个临时引用。因此,在 .then 不再阻塞之前,存在对该对象的引用,因此无法收集它
  2. 你说得对,doMoreWork 也是不可收集的,因为 Promise 对象引用了它

语句doWork().then(...)可以替换为

new Promise(function (resolve, reject) {
  // work work work...
}).then(function doMoreWork () {
          // Some more work to do...
        })

所以你可以想象你是直接使用Promise对象,所以"Upper"-Scope就是使用对象的地方。

对象通常在没有更多引用时被收集。即使代码在 Promise 中,它也只是一个对象,并且对 then 的调用是链接的,因此正在使用该对象

没有任何东西保留对 promise 的引用,因此它将被垃圾收集。 promise 是唯一保持对函数 doMoreWork 的引用,因此它也会被垃圾收集。

How could I empirically observe this behaviour? In other words, how can I monitor what objects are being GC-ed and when? I develop purely in Node.js, if that makes any difference.

V8 中的 GC 不一定会收集对象。例如,如果这是你的整个程序,那么首先 运行 任何 GC 都是浪费时间。

要查看一个对象是否可垃圾回收,您可以创建一个测试并查找内存泄漏(通过任务管理器)。如果您的代码编写正确,所有内容都会被收集。