是否会使用 GC 从浏览器内存中删除不在 DOM 中但带有附加句柄的元素?
Will element not in DOM but with attached handlers be removerd from browser memory using GC?
为了在我的 js 脚本中获取图像尺寸,我创建了临时 <img>
元素,但没有将其附加到 DOM。这是我写的一个函数的简化版本:
function testImage(i) {
let tester = document.createElement('img');
tester.onload = function() { console.log(tester.naturalWidth); }
tester.src = `${i}.jpg`;
}
tester
仅在函数内部使用。
tester
永远不会达到 DOM。
- onload 函数有一些与此相关的操作
tester
。不知道会不会干扰垃圾收集器
让我们假设这可以被调用很多很多次。那些测试人员会消耗内存吗?或者垃圾收集器会删除它们吗?
PS: 控制台 for (let k=0; k < 1000000000; k++) { testImage(k) }
吞噬了我的全部记忆。
PS2: 我知道我可以编写脚本来重用相同的 <img>
元素。但我对第一种方法很好奇。
UPD: 正如@rojo 所说的 GC 清理内存,但我没有注意到它,因为:
看起来 GC 不会在同步循环中清理内存(至少在浏览器中)。 for (let k=0; k < (1000*1000); k++) { testImage(k) }
行占用大量内存,但是使用 setTimeout
执行 1000 次测试的 1000 次循环重复不会占用太多内存。手动执行不同大小的循环显示循环完成后释放内存。
此特定脚本将许多日志写入浏览器控制台。如果控制台打开,它会消耗更多内存来保存日志。当我重写测试器以防止日志记录时,打开控制台的内存消耗减少了,但 GC 的工作方式相同。
基于MDN(向下滚动至限制:循环引用),这些变量将被删除。
在函数内创建的所有变量都将在函数结束后删除,无一例外。
function foo() {
var a = "data";
console.log(a); // "data"
} // variable is deleted
console.log(a); // Uncaught ReferenceError: a is not defined
为了在我的 js 脚本中获取图像尺寸,我创建了临时 <img>
元素,但没有将其附加到 DOM。这是我写的一个函数的简化版本:
function testImage(i) {
let tester = document.createElement('img');
tester.onload = function() { console.log(tester.naturalWidth); }
tester.src = `${i}.jpg`;
}
tester
仅在函数内部使用。tester
永远不会达到 DOM。- onload 函数有一些与此相关的操作
tester
。不知道会不会干扰垃圾收集器
让我们假设这可以被调用很多很多次。那些测试人员会消耗内存吗?或者垃圾收集器会删除它们吗?
PS: 控制台 for (let k=0; k < 1000000000; k++) { testImage(k) }
吞噬了我的全部记忆。
PS2: 我知道我可以编写脚本来重用相同的 <img>
元素。但我对第一种方法很好奇。
UPD: 正如@rojo 所说的 GC 清理内存,但我没有注意到它,因为:
看起来 GC 不会在同步循环中清理内存(至少在浏览器中)。
for (let k=0; k < (1000*1000); k++) { testImage(k) }
行占用大量内存,但是使用setTimeout
执行 1000 次测试的 1000 次循环重复不会占用太多内存。手动执行不同大小的循环显示循环完成后释放内存。此特定脚本将许多日志写入浏览器控制台。如果控制台打开,它会消耗更多内存来保存日志。当我重写测试器以防止日志记录时,打开控制台的内存消耗减少了,但 GC 的工作方式相同。
基于MDN(向下滚动至限制:循环引用),这些变量将被删除。
在函数内创建的所有变量都将在函数结束后删除,无一例外。
function foo() {
var a = "data";
console.log(a); // "data"
} // variable is deleted
console.log(a); // Uncaught ReferenceError: a is not defined