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您在最初的问题中没有说明,当您使用该超时时,数组数据仍然存在,但当您使用从不解析承诺时,它已被释放?