首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在fetch中修复或解决这个内存泄漏问题?

问如何在fetch中修复或解决这个内存泄漏问题?
EN

Stack Overflow用户
提问于 2021-11-11 17:32:49
回答 1查看 679关注 0票数 2

类似于这个问题:Fetch API leaks memory in Chrome

当使用fetch定期轮询数据时,Chrome的内存使用量不断增加,而不会释放内存,这最终会导致崩溃。

https://jsfiddle.net/abfinz/ahc65y3s/13/

代码语言:javascript
复制
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选项卡收集垃圾,也并不总是释放所有内存。

  • 内存没有出现在JS堆中。我必须使用任务管理器来查看it.
  • Occasionally,--在主动轮询时,内存将清除,但不可避免地会构建到极端级别。
  • Edge也显示了问题,但在清除内存方面似乎更加主动。虽然它最终仍然构建为1GB+的额外内存使用.

我是不是做错什么了,还是这是个窃听器?对于如何在没有内存泄漏的情况下使这种轮询长期工作,有什么想法吗?

EN

回答 1

Stack Overflow用户

发布于 2021-11-13 00:49:02

我使用了它,它似乎是一个处理响应的bug,这样如果您没有调用任何响应函数,它就不会释放分配的内存。

如果我在这里使用这个执行顺序启动代码片段,则chrome任务管理器和windows任务管理器不断报告相同大小的30 MB。同时,它也运行在jsfiddle上,根据请求#120运行30 MB。

​

​

​

代码语言:javascript
复制
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();
    })
}()

​

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69932559

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档