【问题标题】:IE6 Frames & Memory LeakIE6 帧和内存泄漏
【发布时间】:2012-04-27 03:38:12
【问题描述】:

在我开始这个问题之前,我明白它的每个方面都是错误的。请记住这一点...

我有一个类似于 CRM 的 Intranet 应用程序,其中包含我继承的 2001 年开发的集成软电话。它基本上是一个集合应用程序,将电话控制与基于 Web 的前端集成以进行帐户管理。 (Genesys 电话和基于 AS400 的收集系统...使用 MQSeries)

在我称其为“生命终结”之前,我正在尽可能地使这个应用程序现代化。作为我尝试使其现代化的一部分,我为我的 JS 功能和 UI 实现了 jQuery 和 jQuery UI。我不会对此感到疯狂,但它已经根深蒂固。

现在,输入问题:我们目前使用的是 IE6,应用程序是使用框架构建的。 jQuery 库的实现从内存的角度揭示了应用程序的类似筛子的性质。它目前在启动时消耗大约 75Mb 的内存,并在大约 2-3 小时后增长到 150Mb - 300Mb 的任何地方。然后浏览器崩溃。

我已将内存泄漏缩小到帧之间的串扰。我已经在 sIEve 和 Drip 中单独测试了这些页面,并且没有发现任何泄漏。但是访问框架集中的页面,这是一个定时炸弹。

我知道答案是重新设计没有框架的应用程序并开始使用更好的浏览器。这样做有两个问题:

  1. 我已经在 IE9 上测试过,问题仍然存在,但有点 更可控

  2. 重新设计应用程序大约需要 50 万美元和 6-12 个月。

有人知道解决“帧泄漏”问题的方法吗?我知道我没有给出任何代码示例,但我只是在寻找一般知识。我在应用程序中的每个页面的 onload 和 onunload 处调用 IE CollectGarbage() 方法,但无济于事。我试过在 jQuery 中调用 empty() 方法。我尝试将document.body 元素的每个子元素设置为null。没有任何工作。

我不希望不得不取消所有这些更改,因为实际上已经实施了一些相当大的成本削减功能。

附加信息

我已设法查明发生内存泄漏的情况。我认为这是帧之间的“串扰”,但似乎在刷新单个帧时会发生内存泄漏。

我设置了一个基本框架集,其中包含同一页面的 5 个实例(我很确定每个 sIEve 都没有泄漏)。

<html>
    <head>
        <title>Frame Leak Test</title>
    </head>
    <frameset cols="*" rows="50%,50%" frameborder="1">
        <frameset cols="33%,33%,34%" rows="100%">
            <frame src="http://npasappgeneqa02/live/" />
            <frame src="http://npasappgeneqa02/live/" />
            <frame src="http://npasappgeneqa02/live/" />
        </frameset>
        <frameset cols="50%,50%" rows="100%">
            <frame src="http://npasappgeneqa02/live/" />
            <frame src="http://npasappgeneqa02/live/" />
        </frameset>
    </frameset>
</html>

正在加载的索引页面在 sIEve 中显示没有泄漏。

当我在 sIEve 中加载框架集页面并单击自动刷新时,没有报告内存泄漏。但是,如果我在单个帧上单击鼠标右键 -> 刷新,则 DOM 中 75% 的加载项会被列为泄漏。

显然,自动刷新相当于F5/shift+F5刷新。这会清除页面的内存。但是当重新加载单个帧时,内存永远不会清除......显然。我的用户必须看到的每个屏幕都会重新加载到主框架中。

我不能简单地刷新框架集,因为框架集中有一个软电话,如果它被刷新或不正确地注销,就会带来世界末日。

有谁知道不用刷新就可以控制框架集内存的方法吗?

【问题讨论】:

  • 为了在一天中将最不同的错误形式塞进一个帖子中并了解它,您将赢得一票。恭喜。对不起,你不得不忍受这个:(
  • sencha.com/forum/… 看起来像是找到了解决类似问题的方法的人。也许这会有所帮助?同样,stackoverflow.com/questions/2312800/ie6-memory-leak-on-refresh 看起来 id 可能有一些相关的想法 - 特别是关于确保 IE6 已完全修补并从头开始编写 javascript 而不是依赖于 JQuery 的想法。
  • @BoltClock - 感谢您的同情。我很想把这件事分开,并将整个事情放在 iframe 和 AJAX 调用上。
  • 我没有答案,我只是想让你知道我为你感到难过。
  • +1 表示一个高质量、清晰、解释清楚的问题。 (哦,祝你好运!)

标签: jquery jquery-ui frames internet-explorer-6


【解决方案1】:

您没有发布任何代码来判断这一点……但其中许多情况是由于对闭包的不当使用造成的。

阅读包括但不限于:

【讨论】:

  • @Prizoner ZERO - 我没有发布代码,因为问题是系统性的。另外,由于它是一个自定义的 Intranet 应用程序,所以我受到了限制。但是你的观点很好。唯一引入的闭包是 jQuery 固有的闭包。我可以回去自己处理这些事件,但我认为这不会有太大变化。感谢您的参考。
  • 寻找您可能多次为单个控件绑定(或重新绑定)相同事件而没有首先取消绑定所述控件的情况......这比您想象的更常见。
  • 听起来合乎逻辑。我来看看。谢谢。
【解决方案2】:

只是想对这种特殊情况进行更新。我认为我已经找到了解决这个内存泄漏问题的可接受的解决方案:

  1. 我没有在需要 UI 元素的页面上使用完整的 jQueryUI 库,而是使用了单独的最小化脚本(uicore + datepicker 等)。
  2. 我尽可能避免使用小部件脚本的 UI 元素,因为这是问题最集中的地方。
    • 一个。这导致我不得不为button 元素和accordion 元素编写自定义脚本。
  3. 由于此应用程序在frameset 中运行,因此使用window 方法(即window.onloadwindow.onunload)不起作用,因为窗口本身仅使用frameset 加载或卸载。为了解决这个问题,我实现了 document.body 方法,特别是 document.body.onbeforeunload 并进行了全局取消绑定以删除任何挂起的引用 ($("*").unbind();)。

使用上面使用的方法,我在 IE6(和 IE8)中 4 小时的内存消耗从 ~200-250Mb 下降到 ~80-95Mb。我的目标是将 8 小时消耗保持在 150Mb 以下,我认为这将完成任务。

感谢大家的帮助。

【讨论】:

    【解决方案3】:

    我建议通过JSLintJSHint 运行您的JS 代码。

    这两个实用程序(*) 是 Javascript 的代码质量检查器。他们抱怨的地方是 JS 代码有效但包含糟糕的编程习惯。

    他们很有可能至少会发现一些导致您出现问题的事情。

    (* JSHint 是 JSLint 的一个分支,但现在它们已经完全不同了,值得一试)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-12-24
      • 1970-01-01
      • 2010-11-06
      • 2014-01-29
      • 2012-04-09
      • 2010-12-02
      • 2013-11-08
      • 2016-05-03
      相关资源
      最近更新 更多