Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/google-chrome/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 用异步方法理解Chrome GC_Javascript_Google Chrome_Garbage Collection - Fatal编程技术网

Javascript 用异步方法理解Chrome GC

Javascript 用异步方法理解Chrome GC,javascript,google-chrome,garbage-collection,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++) {

我试图弄清楚一个永远不会恢复的异步函数是否会造成内存泄漏。例如:

  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
  }
功能超时(毫秒){
返回新承诺(resolve=>setTimeout(resolve,ms));
}
功能测试(){
this.arr=[];
this.alloc=异步函数(){
对于(i=0;i<300000;i++){
this.arr.push(document.createElement('div');
}
等待超时(10000);
警报('done waiting'+this.arr.length);//输出300000
};
};
var测试=新测试();
函数泄漏(){
test.alloc();
test=null;
window.gc();//使用expose-gc标志运行chrome
//这里的快照内存显示div已被释放
}
使用Chrome的内存工具,我在代码执行完毕后抓取了一个快照。我本希望看到300000个HTMLIDevents仍然被分配,但瞧,内存似乎“被释放了”。奇怪的是,如果我尝试访问数组内容,它们仍然存在。 有人能解释这种现象吗

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

您的
someForeverPromise
本身被垃圾收集,所有仍在等待它的回调都被垃圾收集,包括
异步函数的恢复

你可以用

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

其中,全局
引用
提供了一种方法来解决防止回调被垃圾收集的承诺。(您还应该确保没有人意外调用
reference
,以确保它处于挂起状态,但我将把它作为练习留给读者)。

哪里记录了
expose gc
标志?如果gc行为怪异并且受到
console.log
(或
alert
)语句存在或不存在的影响,我的猜测是,
await
会启用相同的功能。但这很奇怪,因为如果我用计时器替换承诺并添加警报,它仍然会显示。@dan计时器确实保留了对其回调的全局引用(
resolve
?),我还使用了以下实现:函数超时(ms){返回新承诺(resolve=>setTimeout(resolve,ms));}现在,如果我等待超时(10000),那么探查器会显示内存已释放,但我仍然收到警报。@Dandan您在最初的问题中没有说明,当您使用该超时时,数组数据仍然存在,但当您使用从不解析承诺时,它已被释放?