首页 > 解决方案 > 是否会使用 GC 从浏览器内存中删除不在 DOM 中但带有附加处理程序的元素?

问题描述

为了在我的 js 脚本中获取图像尺寸,我创建了临时<img>元素而不将其附加到 DOM。这是我编写的函数的简化版本:

function testImage(i) {
    let tester = document.createElement('img');
    tester.onload = function() { console.log(tester.naturalWidth); }
    tester.src = `${i}.jpg`;
}
  1. tester仅在函数内部使用。
  2. tester永远不会被绑定到 DOM。
  3. onload 函数与此有关tester。我想知道它是否会干扰垃圾收集器。

让我们假设这可以被调用很多很多次。那些测试人员会消耗内存吗?或者垃圾收集器会删除它们吗?

PS:控制台for (let k=0; k < 1000000000; k++) { testImage(k) }吃掉了我的全部记忆。

PS2:我知道我可以编写脚本来重用相同的<img>元素或元素。但我对第一种方法很好奇。

UPD:正如@rojo所说,GC会清理内存,但在我的情况下我没有注意到它,因为:

  1. 看起来 GC 不会在同步循环中清理内存(至少在浏览器中)。该行for (let k=0; k < (1000*1000); k++) { testImage(k) }会占用大量内存,但执行 1000 次测试的 1000 次循环setTimeout不会消耗太多内存。手动执行不同大小的循环表明循环完成后内存释放。

  2. 此特定脚本将许多日志写入浏览器控制台。如果控制台是打开的,它会消耗更多的内存来保存日志。当我重写测试器以防止日志记录时,打开控制台的内存消耗减少了,但 GC 的工作方式相同。

标签: javascriptfirefoxbrowsergarbage-collection

解决方案


基于MDN(向下滚动到限制:循环引用),这些变量将被删除。

一旦函数完成,函数内部创建的所有变量都将被删除,没有例外。

function foo() {
  var a = "data";
  console.log(a); // "data"
} // variable is deleted
console.log(a); // Uncaught ReferenceError: a is not defined

推荐阅读