JavaScript事件处理程序总是增加浏览器内存使用量 [英] Javascript event handlers always increase browser memory usage

查看:169
本文介绍了JavaScript事件处理程序总是增加浏览器内存使用量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

编辑:进一步检查Firefox似乎并没有这样做,但Chrome绝对是这样。我想它只是一个新的浏览器的错误 - 对于每个事件,I / O读取也发生在Chrome中,但不在FF中。



当我加载以下页面浏览器(我已经在Chrome和Firefox 3在Vista下进行了测试),并将鼠标移动到内存上总是会增加,而且似乎没有退缩。




  1. 浏览器中的预期行为

  2. 浏览器中的内存泄漏或

  3. 所提供代码中的内存泄漏?

>
< html>
< head>
< meta http-equiv =Content-Typecontent =text / html; charset = iso-8859-1/>
< title> test< / title>
< / head>
< body>
< script>
var createEl = function(i){
var el = document.createElement(div);
var t = document.createTextNode(i.toString());
el.appendChild(t);
t = null;
el.id = i.toString();

var fn = function(e){};
el.addEventListener(mouseover,fn,false);
//el.onmouseover = fn;
fn = null;

try {
return el;
}
finally {
el = null;
}
// return(el = [el])。pop();
};

var i,x; (i = 0; i <100; i ++){
x = createEl(i)
document.body.appendChild(x);

x = null;
}
< / script>
< / body>
< / html>

(el = [el] .pop()) try / finally 的想法都来自 $ b

我还尝试使用addEventListener和onmouseover添加事件的方法。我发现防止内存增加的唯一方法是注释两行代码。

与事件相关的内存泄漏一般来说,处理程序与外壳有关。换句话说,将函数附加到指向其元素的事件处理程序可以阻止浏览器进行垃圾收集。 (值得庆幸的是,大多数较新的浏览器已经学到了窍门,并且在这种情况下不再泄漏内存,但是很多旧版浏览器都在那里浮动!)



这样的外壳可能如下所示:

  var el = document.createElement(div); 
var fnOver = function(e){
el.innerHTML =Mouse over!;
};
var fnOut = function(e){
el.innerHTML =鼠标输出。
};

el.addEventListener(mouseover,fnOver,false);
el.addEventListener(mouseout,fnOut,false);

document.getElementsByTagName(body)[0] .appendChild(el);

事实上, fnOver fnOut 伸出其附近的范围来引用 el 是创建一个机箱(两个,实际上是每个功能一个),可以导致浏览器泄漏。你的代码不会这样做,所以不要创建任何外壳,所以不应该导致(行为良好的)浏览器泄漏。



只是其中一个的beta软件,我猜。 : - )


Edit: On further examination Firefox does not seem to be doing this, but Chrome definitely does. I guess its just a bug with a new browser - for every event an I/O Read also occurs in Chrome but not in FF.

When I load the following page in a browser (I've tested in Chrome and Firefox 3 under Vista) and move the mouse around the memory always increases and does not ever seems to recede.

Is this:

  1. expected behaviour from a browser
  2. a memory leak in the browser or
  3. a memory leak in the presented code?

.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
    <title>test</title>
</head>
<body>
   <script>
      var createEl = function (i) {
          var el = document.createElement("div");
          var t = document.createTextNode(i.toString());
          el.appendChild(t);
          t=null;
          el.id=i.toString();

          var fn = function (e) {};
          el.addEventListener("mouseover", fn, false);
          //el.onmouseover = fn;
          fn = null;

          try{
            return el;
          }
          finally{
            el=null;
          }
          //return (el = [el]).pop();
        };

        var i,x;
        for (i= 0; i < 100; i++){
          x = createEl(i)
          document.body.appendChild(x);
          x = null;
        }
   </script>
</body>
</html>

The (el = [el].pop()) and the try/finally ideas are both from here, though they do not either seem to help - understandably since they are only meant to be ie6 fixes.

I have also experimented with using the addEventListener and the onmouseover methods of adding the events. The only way I have found to prevent memory from increasing is to comment out both lines of code.

解决方案

Memory leaks related to event handlers are, generally speaking, related to enclosures. In other words, attaching a function to an event handler which points back to its element can prevent browsers from garbage-collecting either. (Thankfully, most newer browsers have "learned the trick" and no longer leak memory in this scenario, but there are a lot of older browsers floating around out there!)

Such an enclosure could look like this:

var el = document.createElement("div");
var fnOver = function(e) {
    el.innerHTML = "Mouse over!";
};
var fnOut = function(e) {
    el.innerHTML = "Mouse out.";
};

el.addEventListener("mouseover", fnOver, false);
el.addEventListener("mouseout", fnOut, false);

document.getElementsByTagName("body")[0].appendChild(el);

The fact that fnOver and fnOut reach out to their enclosing scope to reference el is what creates an enclosure (two, actually — one for each function) and can cause browsers to leak. Your code doesn't do anything like this, so creates no enclosures, so shouldn't cause a (well-behaved) browser to leak.

Just one of the bummer of beta software, I guess. :-)

这篇关于JavaScript事件处理程序总是增加浏览器内存使用量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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