使用异步方法了解Chrome GC

时间:2017-07-15 01:36:32

标签: javascript google-chrome garbage-collection

我正在试图弄清楚是否可以通过永不恢复的异步函数创建内存泄漏。例如:

  function timeout(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
  }

  function Test() {
    this.arr = [];

    this.alloc = async function() {
      for (i = 0; i < 300000; i++) {
        this.arr.push(document.createElement('div'));
      }
      await timeout(10000);
      alert('done waiting ' + this.arr.length); // outputs 300000
    };
  };

  var test = new Test();

  function leak() {
    test.alloc();
    test = null;
    window.gc(); // Running chrome with expose-gc flag
    // Snapshotting memory here shows divs have been deallocated
  }

使用Chrome的内存工具,我在此代码执行完毕后抓取了一个快照。我本来期望看到仍然分配300000个HTMLDivElements,但是看起来 - 内存似乎“被释放”了。奇怪的是,如果我尝试访问数组内容,它们仍然存在。 任何人都能解释这种现象吗?

1 个答案:

答案 0 :(得分:1)

  

如果我用计时器替换someForeverPromise,然后尝试访问它们仍然存在的数组内容

你的someForeverPromise本身是垃圾收集的,并且还有所有仍在等待它的回调 - 包括恢复async function

您可以使用

const foreverPendingPromise = new Promise(resolve => {
    global.reference = resolve;
});

全局reference保持一种解决承诺的方法,以防止回调被垃圾收集。 (你还应该确保没有人不小心打电话给reference以确保它保持待定状态,但我会将其作为练习留给读者。)