【问题标题】:Will element not in DOM but with attached handlers be removerd from browser memory using GC?是否会使用 GC 从浏览器内存中删除不在 DOM 中但带有附加句柄的元素?
【发布时间】:2021-04-29 14:55:51
【问题描述】:

为了在我的 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) } 行会占用大量内存,但是使用 setTimeout 执行 1000 次测试的 1000 次循环重复并不会消耗太多内存。手动执行不同大小的循环显示循环结束后内存释放。

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

【问题讨论】:

  • 我推荐阅读Memory Management (MDN)。我认为变量每次都会被删除。
  • “吃掉我的全部记忆”,但它真的会进行垃圾收集吗?
  • @JonasWilms 我认为吃掉大量内存意味着垃圾仍在内存中。
  • 是的。但它仍然可以用于垃圾收集,只是 GC 没有循环。大多数浏览器仅在压力下收集(内存已满时)

标签: javascript firefox browser garbage-collection


【解决方案1】:

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

函数内部创建的所有变量将在函数完成后被删除,无一例外。

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

【讨论】:

  • 我没有发现垃圾收集何时开始。有什么想法吗?
  • @AlexanderChzhen 它在函数完成时启动。它在变量被删除时结束。
  • 您有任何文档证明 GC 仅在同步函数结束后才开始?
  • @AlexanderChzhen 它在文档中有所暗示。同样在GeeksForGeeks(滚动到循环不再有问题,大约一半),他们说分配被回收。当然,这取决于计算机的速度,但它应该立即启动或在一两毫秒内启动。
  • @AlexanderChzhen 另外,您可能想问JS room。只需询问是否在函数结束后立即开始垃圾收集
猜你喜欢
  • 1970-01-01
  • 2014-05-22
  • 1970-01-01
  • 1970-01-01
  • 2015-01-29
  • 1970-01-01
  • 2011-01-15
  • 1970-01-01
  • 2020-10-20
相关资源
最近更新 更多