javascript - 如何控制IE6+jQuery+jQuery-ui内存泄漏?

标签 javascript jquery jquery-ui memory-leaks internet-explorer-6

这是一个sample page和几个日期选择器。这是 Drip 结果:

alt text http://www.picvault.info/images/537090308_omoya.png

当我反复单击“刷新”按钮时,此页面在 IE6sp1 中无限期泄漏(IE6sp3+、Opera 9、Chrome2 和 FF3+ 似乎都不错)。内存会上升并且永远不会下降,直到我真正完全关闭浏览器。

我也尝试过使用最新的 jquery nightly (r6414) 和最新的稳定 UI (1.7.2),但没有任何区别。我尝试了各种方法但没有成功( CollectGarbageAntiLeak 、其他)。

我正在寻找“使用不同的浏览器!!1”之外的解决方案,因为我对此没有任何控制权。任何帮助将不胜感激!

更新 1: 我将该按钮事件添加到循环中,这就是发生的情况(突然下降是在我终止 IE 时): alt text

更新 2:我提交了 bug report (手指交叉)。

更新 3: 这也位于 mailing list 上.

更新 4:这(如邮件列表中所报告的那样)不起作用,实际上会使事情变得更糟:

$(window).bind("unload", function() {
  $('.hasDatepicker').datepicker('destroy');
  $(window).unbind();
}); 

仅仅调用 destroy 是不够的。我仍然被这个问题困扰,并且非常接近将 jquery 从该项目中剥离出来。我喜欢它(我真的很喜欢!),但如果它坏了,我就无法使用它。

更新 5:开始赏金,另外 550 点奖励给一位乐于助人的个人!

更新 6:更多测试表明 IE6 和 IE6sp1 中存在此泄漏,但已在 IE6sp2+ 中修复。现在,关于我迄今为止得到的答案......

到目前为止,所有答案都是以下任何一个:

  1. 放弃 IE6sp0/sp1 用户或忽略 他们
  2. 自己调试 jquery 并解决问题
  3. 我无法重现该问题。

我知道乞丐不能挑剔,但这些根本不能解决我的问题。

我不能放弃我的用户。他们占用户群的 25%。这是为客户编写的自定义应用程序,设计用于 IE6。 放弃 IE6sp0/sp1 不是一个选择。这不是告诉我的客户只处理它的选择。它泄漏得如此之快,以至于五分钟后,一些较弱的机器就无法使用了。

此外,虽然我很想成为一名 JS 忍者,这样我就可以在 jquery 代码中找出模糊的内存泄漏(当然这是 MS 的错误,而不是 jquery 的错误),但我也没有看到这种情况发生。

最后,很多人在此处和邮件列表中重现了该问题。如果您无法重现它,您可能拥有 IE6SP2+,或者您可能不够清爽。

显然这个问题对我来说非常重要(因此有 6 次修订、赏金等),因此我愿意接受新想法,但请记住,这三个建议都不适合我。

感谢大家的考虑和见解。请让他们继续来!

更新 7: 赏金已结束,SO 自动接受 Keith 的回答。很抱歉,只获得了一半的分数(因为我自己没有选择答案),但我仍然很困惑,所以我认为一半是公平的。

我希望 jquery/jquery-ui 团队能够解决这个问题,但我担心我必须将其写为“不可能(目前)”并停止使用部分或全部 jquery。感谢大家的帮助和考虑。如果有人真正解决了我的问题,请发布,我会想办法奖励你。

最佳答案

我不想这么说,你的方法是正确且专业的,但我很想离开它。

不解决此问题的后果是 IE6 用户会发现他们的计算机变得越来越慢,最终要么完全崩溃,要么更有可能使 IE6 崩溃。

那又怎样?

真的 - 为什么这是你的问题?

您的网站绝对不会是他们访问的唯一存在此漏洞的网站,而且无论您做什么,他们都会定期看到 IE6 崩溃,因为这就是它的作用。

仍然使用 IE6 的任何人都不太可能指出您的应用程序存在泄漏。

最后,当 IE6 确实崩溃时,它会将 IE6 报告为罪魁祸首 - 您可以合理地指出这是 IE6 中的一个错误,微软已在新版本中修复了该错误。

您的宝贵时间最好花在为那些不陷入遗留 hell 的用户改进应用程序上 - 您的应用程序基本上应该适用于 IE6 用户,但此类问题可能会占用您所有的时间,并且无法解决他们的问题。 IE6 仍然是一个不受支持、崩溃、安全漏洞的浏览器。

我怀疑 jQuery 开发人员与我持类似的观点。此外,您还必须做一些非常丑陋的事情来解决 IE6 中的这个错误,包括阻止泄漏的 hacky DOM 工作,但实际上速度要慢得多。

<小时/>

更新

好吧,这不是一个容易修复的问题 - MS 在这里描述了 IE6 错误(并提供了如何修复它的建议):http://msdn.microsoft.com/en-us/library/bb250448(VS.85).aspx

基本上这不是 javascript 或 jQuery 的问题 - 实际问题在于 IE6 DOM - 当 HTML 元素添加到页面时(通过 javascript,而不是在加载时添加到页面中),IE 不能垃圾收集它们,除非它们是以非常特定的方式创建的。

这与 jQuery UI 构建元素的方式是从后到前的(请参阅上面链接中的 DOM 插入顺序错误),因此这不是 jQuery 开发人员或您可以轻松修复的问题。

那么如何解决这个问题呢?好吧,您可以继续使用 IE6 的旧弹出式日历,也可以编写自己的日历。

我推荐前者,但如果您确实想构建后者,则需要遵循一些基本规则:

  1. 始终从上到下添加元素 - 例如,如果您想构建一个表格,请添加 <table>元素到页面的 DOM 中,然后添加 <tr>然后<td>等等。这是从后到前的,因为构建整个表然后将其添加到 DOM 中要快得多 - 不幸的是 IE6 就失去了对它的跟踪。

  2. 仅使用 CSS 和 HTML 3.2 属性 - 听起来很愚蠢,但 IE6 会创建额外的对象来存储额外的属性(或“expando”属性),而这些也会泄漏。

  3. 与 (2) 有点相关,但正如 @gradbot 提到的,IE6 在垃圾收集 javascript 变量方面存在问题 - 如果它们在从该元素触发的事件中引用 DOM 元素,您可能会遇到问题。 JavaScript 对具有“expando”属性的 DOM 元素的引用也使情况更加复杂。

如果您在网上浏览一下,可能已经有一个遵守这些规则的下拉式 DHTML 日历 - 它不会像 jQuery UI 那样漂亮、快速或可配置,但我确信我'我们已经在 IE6 中看到它没有泄漏。

我认为最好的选择是尽可能保持静态 - 例如,您可以使用页面加载日历网格(周数字和日列标题),然后动态加载数字(而不是其他内容)。将日期数字创建为链接,并在 href 中使用 javascript - 通常不是最佳实践,但在 IE6 中泄漏的可能性要小得多。

关于javascript - 如何控制IE6+jQuery+jQuery-ui内存泄漏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1051090/

相关文章:

javascript - 使用 jquery 删除元素上的验证器

javascript - 选中子复选框上的所有复选框

javascript - goog.require 和 goog.addDependency 有什么区别?

javascript - 询问有关 cordova device.uuid javascript 的信息?

jquery - 解除div的绑定(bind),稍后再绑定(bind)

javascript - 从功能开始或不开始的区别,我需要一些理解

javascript - Electron:.setAttribute 不起作用(不同)

javascript - 如何使MathJax.js的源(路径)环境依赖?

javascript - jQuery ui 可排序 : How to disallow the nesting of groups while allowing all the items to be inter-sortable

Jquery:最小化 Accordion 标签点击标签内容