在闭包中引用DOM元素的IE内存泄漏? [英] IE memory leak from referencing DOM elements in closures?

查看:181
本文介绍了在闭包中引用DOM元素的IE内存泄漏?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在最近的一次采访中,我被问到:在引用DOM元素时使用闭包有什么危险,比如这个代码呢?

During an interview recently, I was asked, "What's dangerous about using closures when referencing DOM elements, like this code does?"

var firstNameValue = (function(elementId) {
    var firstName = document.getElementById(elementId);
    return firstName.value;
})("firstName");

显然,我不知道,上面的代码会在IE中造成内存泄漏。给出的理由很模糊,我不明白,但显然这可能仅适用于较旧的IE版本?

Apparently, unbeknownst to me, the above code creates a memory leak in IE. The given rationale was pretty vague and I didn't understand it, but apparently this may only apply to older IE versions?

任何人都可以详细说明这个吗?

Anyone can elaborate on this?

推荐答案

用于处理由/为DOM分配的内存的垃圾收集器不知道如何释放可能存在的内存悬挂在JScript引擎分配的位置。因此,它只是忽略了这些事情。

The garbage collector used in the guts of IE to deal with memory allocated by/for the DOM has no idea how to free memory that may be dangling along allocated by the JScript engine. Thus, it just ignores such things.

所以你将一个事件处理程序绑定到一个DOM元素(或类似的东西),你的事件处理程序是一个在一个内部创建的函数。调用其他一些函数,并且其他函数有一个包含十亿个东西的本地数组,那么,在DOM元素本身被废弃之后,甚至在页面之后很长时间内,这些数十亿的东西依然存在。包含它的em已被释放(我认为;它已经有一段时间了)。

So you bind an event handler to a DOM element (or something like that), and your event handler is a function created inside an invocation of some other function, and that other function has a local array with a billion things in it, well, those billion things live on and on long after the DOM element itself is junked, and even long after the page that contained it has been freed (I think; it's been a while).

function bindHandler(domElement) {
  var hoHumWhatever = generateGiganticObjectNow();

  domElement.onclick = function() {
    alert("oww you clicked me");
  };
}

现在在闭包中保留了hoHumWhatever变量。当重新加载页面或修改DOM以使元素被丢弃时,DOM垃圾收集器将无法对指向JScript拥有的内存的属性执行任何操作。另一方面,JScript不知道DOM节点已被释放,因此它认为仍然引用了闭包内存。

Now that "hoHumWhatever" variable is maintained in the closure. When the page is reloaded or the DOM modified such that the element is thrown away, the DOM garbage collector will fail to do anything with the attribute that's pointing into JScript-owned memory. JScript, on the other hand, doesn't know that the DOM node has been freed, so it thinks the closure memory is still referenced.

我承认这可能是某些细节不准确,但这是基本问题。各种各样的人都写过这个,包括Crockford先生和(我认为)ppk在quirksmode。

I admit that this may be inaccurate in some particulars, but that's the basic problem. Various people have written about this, including Mr. Crockford and (I think) ppk at quirksmode.

edit 在仔细阅读您发布的代码后,我认为可能是类似但相反情况的示例:little函数返回对DOM值的一部分的引用,也许有人说JScript会挂在DOM内存上(而不是相反)。现在,在这种特殊情况下,我有点怀疑,因为除了对DOM属性的简单引用之外,我没有看到有什么东西从该闭包中逃脱,DOM属性应该是一个原始的字符串实例,所以它真的不应该引起问题。这些事情可能具有欺骗性,但我只会坐在这里划伤我的头。

editUpon more carefully rereading the code you posted, I think that might be an example of the similar but opposite case: the little function returns a reference to a part of a DOM value, so maybe somebody's saying that JScript will hang onto the DOM memory (instead of vice-versa). Now, in this particular case, I'm a little doubtful, because I don't see how anything "escapes" from that closure except the simple reference to the DOM attribute, which should be a primitive string instance and so which really shouldn't cause a problem. These matters can be deceptive however so I'll just sit here and scratch my head.

这篇关于在闭包中引用DOM元素的IE内存泄漏?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆