这是一个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),但没有任何区别。我尝试了各种方法但没有成功( CollectGarbage 、 AntiLeak 、其他)。
我正在寻找“使用不同的浏览器!!1”之外的解决方案,因为我对此没有任何控制权。任何帮助将不胜感激!
更新 1: 我将该按钮事件添加到循环中,这就是发生的情况(突然下降是在我终止 IE 时):
更新 2:我提交了 bug report (手指交叉)。
更新 3: 这也位于 mailing list 上.
更新 4:这(如邮件列表中所报告的那样)不起作用,实际上会使事情变得更糟:
$(window).bind("unload", function() {
$('.hasDatepicker').datepicker('destroy');
$(window).unbind();
});
仅仅调用 destroy 是不够的。我仍然被这个问题困扰,并且非常接近将 jquery 从该项目中剥离出来。我喜欢它(我真的很喜欢!),但如果它坏了,我就无法使用它。
更新 5:开始赏金,另外 550 点奖励给一位乐于助人的个人!
更新 6:更多测试表明 IE6 和 IE6sp1 中存在此泄漏,但已在 IE6sp2+ 中修复。现在,关于我迄今为止得到的答案......
到目前为止,所有答案都是以下任何一个:
- 放弃 IE6sp0/sp1 用户或忽略 他们
- 自己调试 jquery 并解决问题
- 我无法重现该问题。
我知道乞丐不能挑剔,但这些根本不能解决我的问题。
我不能放弃我的用户。他们占用户群的 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 的旧弹出式日历,也可以编写自己的日历。
我推荐前者,但如果您确实想构建后者,则需要遵循一些基本规则:
始终从上到下添加元素 - 例如,如果您想构建一个表格,请添加
<table>
元素到页面的 DOM 中,然后添加<tr>
然后<td>
等等。这是从后到前的,因为构建整个表然后将其添加到 DOM 中要快得多 - 不幸的是 IE6 就失去了对它的跟踪。仅使用 CSS 和 HTML 3.2 属性 - 听起来很愚蠢,但 IE6 会创建额外的对象来存储额外的属性(或“expando”属性),而这些也会泄漏。
与 (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/