动态 iframe src 更改导致内存泄漏
Dynamic iframe src change causes memory-leak
我正在测试 Vue
模板中 <iframe>
的 src
属性 的动态变化。在测试中,我每秒更改一次 src。在几分钟内,我的可用内存被使用了 88%,最终电脑死机了。我在具有 32 GB 内存和 Firefox 浏览器的 Windows 10 机器上执行了此测试。
但是,我首先注意到使用铬浏览器在 Raspberry Pi 4 (4GB) 上使用类似方法的内存问题。我不断地切换多个 vue 组件(比如幻灯片)。其中一些也有 iframes
。就像上面的测试一样,内存泄漏(不是那么快,但在几天之内),铬浏览器选项卡崩溃,显示 he's dead jim 笑脸。
这是测试的代码:
<template>
<div id="app">
<iframe :src="src" />
{{ count }}
{{ src }}
</div>
</template>
<script>
export default {
data() {
return {
src : "",
source : [
"https://example.com/embeddedcontent/1",
"https://example.com/embeddedcontent/2",
"https://example.com/embeddedcontent/3",
"https://example.com/embeddedcontent/4"
],
count : 0,
interval : null
}
},
mounted() {
const interval = setInterval(() => {
this.src = this.source[ this.count % this.source.length ];
this.count = this.count + 1
}, 2000);
this.interval = interval;
},
beforeDestroy() {
clearInterval(this.interval);
}
}
</script>
事实
- 在不同的系统和浏览器上注意到相同的内存泄漏(
Win10/Firefox
、Raspbian/chromium-browser
)
- 在 Vue 的开发 (HMR) 和生产构建期间注意到相同的内存泄漏。尽管单独的 Vue 应用程序。
- 我不知道 iframe 的内容,可以是任何内容,因为
src
属性 可以设置为任何 URL.
有什么办法可以防止这种情况发生吗?
到目前为止,我只想每隔几分钟刷新一次浏览器选项卡。这将是一种 hacky 解决方案,因为它没有解决问题的根源。当我想在我的 Vue 应用程序中显示另一个网站内容时,是否有使用 iframes
的替代方法?有没有办法只清理整个 iframe
而不会留下任何东西?
更新 2021/02/25
我现在也尝试了 Edge 浏览器,结果相同(增加内存超时)。我还尝试了 Firefox Private 模式,影响很小(增加内存但有点慢)。比较 vue 示例的生产和开发构建,没有区别。我还尝试了一个带有以下代码(无 vue)的香草电子应用程序:
let interval = null;
let sources = [
"https://hurtigruten.panomax.com/ms-roald-amundsen",
"https://hurtigruten.panomax.com/ms-fridtjof-nansen",
"https://rosenalp.panomax.com/",
"https://alpbach.panomax.com/galtenberg",
];
let index = 0;
let count = 0;
function startTheInterval() {
interval = setInterval(() => {
index = count % sources.length;
count = count + 1;
document.getElementById('monitor').src = sources[index];
},2000);
}
function clearTheInterval() {
clearInterval(interval);
}
startTheInterval();
同样的结果,快速增加内存。
首先,关于 iframe
如何在浏览器中工作的一些理论 - Detached window memory leaks
当您尝试调试内存泄漏时,请始终使用“隐身模式”- 当浏览器 未使用 任何扩展时的模式。扩展可以保持对 HTML 的引用加载到 iframe
中并保持该数据有效。当我在 Chrome 中分析您的示例时,仅切换到隐身模式会导致内存分配和保留的大幅减少...
不要使用 Vue CLI/Webpack 开发模式来调试内存泄漏。 Webpack 的热模块重新加载 (HMR) 会影响内存中保存的内容。始终为此使用生产版本...
请注意,JS 运行 次(在本例中为 V8)收集一些关于正在执行的代码的元数据和 keep it in the JS heap。看起来像内存泄漏的可能只是 JS 虚拟机元数据...
更新:
我已经 运行 在我的开发机器(Ryzen 5 3600、32G RAM、Win 10 x64)上使用您的示例(间隔为 1 秒而不是 2 秒)进行了一些测试 - 由 serve-handler
提供的生产构建加载到Firefox Developer Edition v86.0b9(64 位)专用 window(因此没有任何类型的扩展)
首先打开 Dev Tools 并打开内存分析(打开 Record call stacks
选项)。一开始拍了一张快照,大约 40 分钟后又拍了一张。比较这些快照没有显示任何 JS 堆分配增加。浏览器的私有字节(使用 Sysinternals Process Explorer)显示增加了大约 60MB,但是当我关闭开发工具时内存被清除了,所以可以肯定地说这是开发工具使用的内存
同样的例子,现在没有打开 Dev Tools - 运行宁 40 分钟。同样没有任何内存增加...
所以我的结论是 iframe
或 Vue 本身没有内存泄漏。如果你真的看到像“几分钟内我的可用内存被使用了 88%”这样戏剧性的事情,你应该检查你自己的系统,尤其是浏览器中安装的扩展....
我正在测试 Vue
模板中 <iframe>
的 src
属性 的动态变化。在测试中,我每秒更改一次 src。在几分钟内,我的可用内存被使用了 88%,最终电脑死机了。我在具有 32 GB 内存和 Firefox 浏览器的 Windows 10 机器上执行了此测试。
但是,我首先注意到使用铬浏览器在 Raspberry Pi 4 (4GB) 上使用类似方法的内存问题。我不断地切换多个 vue 组件(比如幻灯片)。其中一些也有 iframes
。就像上面的测试一样,内存泄漏(不是那么快,但在几天之内),铬浏览器选项卡崩溃,显示 he's dead jim 笑脸。
这是测试的代码:
<template>
<div id="app">
<iframe :src="src" />
{{ count }}
{{ src }}
</div>
</template>
<script>
export default {
data() {
return {
src : "",
source : [
"https://example.com/embeddedcontent/1",
"https://example.com/embeddedcontent/2",
"https://example.com/embeddedcontent/3",
"https://example.com/embeddedcontent/4"
],
count : 0,
interval : null
}
},
mounted() {
const interval = setInterval(() => {
this.src = this.source[ this.count % this.source.length ];
this.count = this.count + 1
}, 2000);
this.interval = interval;
},
beforeDestroy() {
clearInterval(this.interval);
}
}
</script>
事实
- 在不同的系统和浏览器上注意到相同的内存泄漏(
Win10/Firefox
、Raspbian/chromium-browser
) - 在 Vue 的开发 (HMR) 和生产构建期间注意到相同的内存泄漏。尽管单独的 Vue 应用程序。
- 我不知道 iframe 的内容,可以是任何内容,因为
src
属性 可以设置为任何 URL.
有什么办法可以防止这种情况发生吗?
到目前为止,我只想每隔几分钟刷新一次浏览器选项卡。这将是一种 hacky 解决方案,因为它没有解决问题的根源。当我想在我的 Vue 应用程序中显示另一个网站内容时,是否有使用 iframes
的替代方法?有没有办法只清理整个 iframe
而不会留下任何东西?
更新 2021/02/25
我现在也尝试了 Edge 浏览器,结果相同(增加内存超时)。我还尝试了 Firefox Private 模式,影响很小(增加内存但有点慢)。比较 vue 示例的生产和开发构建,没有区别。我还尝试了一个带有以下代码(无 vue)的香草电子应用程序:
let interval = null;
let sources = [
"https://hurtigruten.panomax.com/ms-roald-amundsen",
"https://hurtigruten.panomax.com/ms-fridtjof-nansen",
"https://rosenalp.panomax.com/",
"https://alpbach.panomax.com/galtenberg",
];
let index = 0;
let count = 0;
function startTheInterval() {
interval = setInterval(() => {
index = count % sources.length;
count = count + 1;
document.getElementById('monitor').src = sources[index];
},2000);
}
function clearTheInterval() {
clearInterval(interval);
}
startTheInterval();
同样的结果,快速增加内存。
首先,关于 iframe
如何在浏览器中工作的一些理论 - Detached window memory leaks
当您尝试调试内存泄漏时,请始终使用“隐身模式”- 当浏览器 未使用 任何扩展时的模式。扩展可以保持对 HTML 的引用加载到
iframe
中并保持该数据有效。当我在 Chrome 中分析您的示例时,仅切换到隐身模式会导致内存分配和保留的大幅减少...不要使用 Vue CLI/Webpack 开发模式来调试内存泄漏。 Webpack 的热模块重新加载 (HMR) 会影响内存中保存的内容。始终为此使用生产版本...
请注意,JS 运行 次(在本例中为 V8)收集一些关于正在执行的代码的元数据和 keep it in the JS heap。看起来像内存泄漏的可能只是 JS 虚拟机元数据...
更新:
我已经 运行 在我的开发机器(Ryzen 5 3600、32G RAM、Win 10 x64)上使用您的示例(间隔为 1 秒而不是 2 秒)进行了一些测试 - 由 serve-handler
提供的生产构建加载到Firefox Developer Edition v86.0b9(64 位)专用 window(因此没有任何类型的扩展)
首先打开 Dev Tools 并打开内存分析(打开
Record call stacks
选项)。一开始拍了一张快照,大约 40 分钟后又拍了一张。比较这些快照没有显示任何 JS 堆分配增加。浏览器的私有字节(使用 Sysinternals Process Explorer)显示增加了大约 60MB,但是当我关闭开发工具时内存被清除了,所以可以肯定地说这是开发工具使用的内存同样的例子,现在没有打开 Dev Tools - 运行宁 40 分钟。同样没有任何内存增加...
所以我的结论是 iframe
或 Vue 本身没有内存泄漏。如果你真的看到像“几分钟内我的可用内存被使用了 88%”这样戏剧性的事情,你应该检查你自己的系统,尤其是浏览器中安装的扩展....