首页 > 解决方案 > 堆叠承诺是否会导致节点内存泄漏?

问题描述

阅读这个线程,我开始怀疑我正在做的事情是否会导致内存泄漏:

下面的代码将使我能够在我的代码库中的任何位置堆叠任务,并确保每个任务仅在之前的所有任务完成后才执行。

function task() {
  //dummy async treatment
  return delay(100);
}
let stack = Promise.resolve('the stack is empty');

function addTask() {
  return stack = stack.then(task);
}

当反复调用addTask时,就像每秒一样,我会有内存泄漏吗?如果我这样做,我应该如何解决这个问题?

非常感谢!

标签: node.jspromisees6-promise

解决方案


当随着时间重复调用 addTask 时,就像每秒一样,我会有内存泄漏吗?如果我这样做,我应该如何解决这个问题?

不会。承诺链将允许链中较早解决的承诺被垃圾收集,因此只要您留出一些时间进行垃圾收集,就不应该有内存积累。

引用的线程创建了一个没有空闲时间的条件,并且它是一个无限循环,因此如果 JS 引擎始终优先为已解决的承诺触发处理程序而不是垃圾收集,则可能会累积内存使用量。由于在大多数 JS 引擎中为已解决的 promise 提供服务是一个非常高优先级的操作,如果某些 JS 引擎在有等待触发它的处理程序的 promise 时不执行任何垃圾收集,我不会感到惊讶.then()

另一方面,您的任务处理程序不是无限循环,并且确实有一些时间进行垃圾收集(就像大多数真正的异步操作一样)。

您应该注意的一件事是,如果您要立即创建数十万个此类任务,它将立即创建数十万个 Promise,这不是调度超大量任务的内存效率最高的机制。例如,将它们存储在一个数组中并在每次完成时从数组中挑选下一个可能更节省内存,因为 promise 对象比数组元素占用更多内存。

另一方面,如果您正在创建数十个甚至数百个任务,并且队列中不会同时有数万个任务,那么您的方案将完美运行。一旦系统进行了一些垃圾收集,与现在已完成的早期任务相关联的已解决承诺将被很好地垃圾收集。


推荐阅读