【问题标题】:Dynamic iframe src change causes memory-leak动态 iframe src 更改导致内存泄漏
【发布时间】:2021-05-14 13:36:34
【问题描述】:

我正在测试Vue 模板中<iframe>src 属性的动态变化。在测试中,我每秒更改一次 src。在几分钟之内,我的可用内存被 88% 使用,最终计算机最终死机。我在具有 32 GB 内存和 Firefox 浏览器的 Windows 10 机器上执行了此测试。

但是,我首先注意到在使用 chromium-browser 的 Raspberry Pi 4 (4GB) 上使用类似方法的内存问题。我不断地切换多个 vue 组件(如幻灯片)。其中一些也有iframes。就像上面的测试一样,内存泄漏(不是那么快,但在几天内),并且 chromium 浏览器选项卡崩溃,显示 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/FirefoxRaspbian/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();

同样的结果,快速增加内存。

【问题讨论】:

    标签: javascript vue.js memory-leaks


    【解决方案1】:

    首先,关于iframe 如何在浏览器中工作的一些理论 - Detached window memory leaks

    1. 当您尝试调试内存泄漏时,请始终使用“隐身模式” - 当浏览器不使用任何扩展时的模式。扩展可以保持对加载到iframe 中的 HTML 的引用并保持该数据处于活动状态。当我在 Chrome 中分析您的示例时,只是切换到隐身模式导致内存分配和保留大量减少......

    2. 不要使用 Vue CLI/Webpack 开发模式来调试内存泄漏。 Webpack 的热模块重载 (HMR) 会影响内存中保存的内容。始终为此使用生产版本...

    3. 请注意,JS 运行时(在本例中为 V8)收集有关正在执行的代码和 keep it in the JS heap 的一些元数据。看起来像内存泄漏的可能只是 JS 虚拟机元数据...

    更新: 我已经在我的开发机器(Ryzen 5 3600、32G RAM、Win 10 x64)上使用您的示例(间隔 1 秒而不是 2 秒)运行了一些测试 - 由 serve-handler 提供的生产构建加载到 Firefox 开发版 v86.0b9 (64 位)私有窗口(因此没有任何类型的扩展)

    1. 首先打开开发工具并打开内存分析(Record call stacks 选项打开)。开始时录制一张快照,大约 40 分钟后再录制一张。比较这些快照并没有显示任何 JS 堆分配增加。浏览器的私有字节(使用 Sysinternals Process Explorer)显示增加了大约 60MB,但在我关闭开发工具的那一刻,内存被清除了,所以可以肯定地说这是开发工具使用的内存

    2. 同样的例子,现在没有打开开发工具 - 运行了 40 分钟。再次没有任何内存增加...

    所以我的结论是没有与iframe 或 Vue 本身相关的内存泄漏。如果你真的看到像“在几分钟内我的可用内存被使用了 88%”这样的戏剧性内容,你应该检查你自己的系统,尤其是浏览器中安装的扩展......

    【讨论】:

    • 好点。但是我不确定我是否正在尝试调试内存泄漏,因为我已经知道 iframe 导致了它。 iframe 内部(src)的内容可能会有所不同,我不知道。从开发到生产构建,问题仍然存在。我会用更多信息更新我的问题。我想我真正想要的是如何避免创建/销毁的 iframe 导致内存泄漏。
    • 我在我的问题中添加了更多信息。是否缺少其他重要信息?
    • 您的更新很有趣,谢谢! - 我也不认为它与 Vue 相关。但我必须再次概述,我在两个非常不同的系统上使用iframe 经历了内存泄漏(一个是使用铬浏览器的树莓派 4,另一个是使用 Firefox 的 Windows 机器)。为了确定,我将检查两个系统上是否涉及任何扩展。 serve-handler 是什么意思?
    • 是的,我理解这个问题 - 只是报告我自己的观察。 serve-handler 是 node 包,它允许您轻松创建本地 HTTP 服务器。我正在使用它在本地运行 Vue 生产版本...
    • 哦,我明白了!在我的特殊情况下,我在 vue.config.js 中使用了 publicPath: "" 选项。使用它,我可以直接在浏览器中打开 Vue 生产版本,而无需通过 HTTP 提供服务。可能会有不同之处,也值得一试
    猜你喜欢
    • 2020-04-24
    • 2015-07-06
    • 2014-06-07
    • 2013-11-20
    • 2011-10-28
    • 2016-01-18
    • 2012-12-13
    • 1970-01-01
    • 2011-01-08
    相关资源
    最近更新 更多