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

Mic*_*ren 28 javascript jquery memory-leaks jquery-ui internet-explorer-6

这是一个带有几个日期选择器的示例页面.这是Drip的结果:

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

当我反复单击"刷新"按钮时,此页面在IE6sp1中无限期泄漏(IE6sp3 +,Opera 9,Chrome2和FF3 +似乎很好).在我完全关闭浏览器之前,内存会上升并且永远不会下降.

我也尝试过使用最新的每晚jquery(r6414)和最新的稳定UI(1.7.2),但它没有任何区别.我尝试了各种各样的事情没有成功(CollectGarbage,AntiLeak,其他).

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

更新1:我将按钮事件添加到循环中,这就是发生的事情(突然下降是我终止IE时): 替代文字

更新2:我提交了一个错误报告(手指交叉).

更新3:这也在邮件列表中.

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

$(window).bind("unload", function() {
  $('.hasDatepicker').datepicker('destroy');
  $(window).unbind();
}); 
Run Code Online (Sandbox Code Playgroud)

仅仅召唤破坏是不够的.我仍然陷入这个问题,并且非常接近将jquery从项目中删除.我喜欢它(我真的很喜欢!)但如果它坏了,我就不能用它了.

更新5:开始赏金,另外550点给一个有用的人!

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

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

  1. 放弃IE6sp0/sp1用户或忽略它们
  2. 调试jquery并自己修复问题
  3. 我不能重复这个问题.

我知道乞丐不能选择,但那些根本不是我问题的答案.

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

此外,虽然我很想成为一个JS忍者,所以我可以在jquery代码中找到模糊的内存泄漏(授予这是MS的错,而不是jquery的),我也没有看到这种情况发生.

最后,多个人在这里和邮件列表上重现了这个问题.如果你不能重新编写它,你可能有IE6SP2 +,或者你可能不够爽快.

显然这个问题对我来说非常重要(因此有6个版本,赏金等等),所以我对新想法持开放态度,但请记住,这三个建议都不适合我.

感谢所有人的考虑和见解.请让他们来!

更新7:赏金已经结束,Keith的答案被SO自动接受.对不起,只有一半的积分被授予(因为我自己没有选择答案),但我仍然真的被卡住了所以我认为一半是公平的.

我希望jquery/jquery-ui团队可以解决这个问题,但我担心我必须把它写成"不可能(现在)"并停止使用部分或全部jquery.感谢大家的帮助和考虑.如果有人为我的问题提供了真正的解决方案,请发帖,我会想出一些奖励你的方法.

Kei*_*ith 22

我讨厌这样说,你的方法是正确和专业的,但我很想离开它.

不解决这个问题的后果是IE6用户会注意到他们的机器越来越慢,最终要么完全崩溃,要么更有可能导致IE6崩溃.

所以呢?

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

你肯定不会是他们访问这个泄漏的唯一网站,他们会看到IE6会定期崩溃,无论你做什么,因为它就是它的作用.

任何仍然在IE6上的人都不太可能指出你的应用程序是泄漏的应用程序.

最后,当IE6崩溃时,它报告IE6是罪魁祸首 - 你可以合理地指出这是微软已经在新版本中修复的IE6中的一个错误.

你的昂贵时间最好用于改善未被困在遗留地狱的用户的应用程序 - 你的应用程序基本上应该适用于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 devs或者你可以轻松修复的东西.

那么你如何解决这个问题呢?好吧,你可以坚持使用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中泄漏的可能性要小得多.

  • @Keith:不幸的是,这是我公司编写的自定义应用程序.有25%的用户在运行<IE6sp3,我无法选择支持 - 相信我,我只想强迫每个人升级.我也明白,糟糕的是jquery必须解决IE的bug,但这就是我喜欢jquery的原因:它让我不再担心浏览器问题和版本等等.或者我认为.如果我无法修复泄漏,我必须撕掉jquery或者至少它的任何部分泄漏并做其他事情. (2认同)