类似于这个问题:Fetch API leaks memory in Chrome
当使用fetch定期轮询数据时,Chrome的内存使用量不断增加,而不会释放内存,这最终会导致崩溃。
https://jsfiddle.net/abfinz/ahc65y3s/13/
const state = {
response: {},
count: 0
}
function poll(){
fetch('https://upload.wikimedia.org/wikipedia/commons/3/3d/LARGE_elevation.jpg')
.then(response => {
state.response = response;
state.count = state.count + 1;
if (state.count < 20){
console.log(state.count);
setTimeout(poll, 3000);
} else {
console.log("Will restart in 1 minute");
state.count = 0;
setTimeout(poll, 60000);
}
});
}
poll();这个JSFiddle很好地演示了这个问题。通过每3秒轮询一次数据,似乎有什么东西导致Chrome不断地保存内存。如果我让它停下来等待几分钟,它通常会释放内存,但是如果轮询继续,它通常会保持它。而且,如果让它运行几个完整的周期,即使强制从dev tools的perfomance选项卡收集垃圾,也并不总是释放所有内存。
我是不是做错什么了,还是这是个窃听器?对于如何在没有内存泄漏的情况下使这种轮询长期工作,有什么想法吗?
发布于 2021-11-13 00:49:02
我使用了它,它似乎是一个处理响应的bug,这样如果您没有调用任何响应函数,它就不会释放分配的内存。
如果我在这里使用这个执行顺序启动代码片段,则chrome任务管理器和windows任务管理器不断报告相同大小的30 MB。同时,它也运行在jsfiddle上,根据请求#120运行30 MB。

const state = {
response: {},
count: 0
},
uri = 'https://upload.wikimedia.org/wikipedia/commons/3/3d/LARGE_elevation.jpg';
!function poll() {
const controller = new AbortController(),
signal = controller.signal;
// using this you can cancel it and destroy it completly.
fetch(uri, { signal })
// this is triggered as soon as the header data is transfered
.then(response => {
/**
* Continung without doing anything on response
* fills the memory.
*
* Chrome downloads the file in the background and
* seems to wait for the use of a call on the
* response.fx() or an abort signal.
*
* This seems to be a bug or a small design mistake
* if response is never used.
*
* If response.json(), .blob(), .body() or .text() is
* called the memory will be free'd.
*/
return response.blob();
}).then((binary) => {
// store data to a var
return state.response = binary;
}).catch((err) => {
console.error(err);
}).finally(() => {
// and start the next poll
console.log(++state.count, state.response.type, (state.response.size / 1024 / 1024).toFixed(2)+' MB');
requestAnimationFrame(poll);
// console.dir(state.response);
// reduces memory a bit more
controller.abort();
})
}()
https://stackoverflow.com/questions/69932559
复制相似问题