Обработчики событий Javascript всегда увеличивают использование памяти браузером - PullRequest
2 голосов
/ 29 января 2009

Редактировать: При дальнейшем рассмотрении Firefox, похоже, не делает этого, но Chrome определенно делает. Я предполагаю, что это просто ошибка в новом браузере - для каждого события чтение ввода-вывода также происходит в Chrome, но не в FF.

Когда я загружаю следующую страницу в браузер (я тестировал в Chrome и Firefox 3 под Vista) и перемещаю мышь вокруг памяти, она всегда увеличивается и, кажется, никогда не отступает.

Это:

  1. ожидаемое поведение от браузера
  2. утечка памяти в браузере или
  3. утечка памяти в представленном коде?

.

<!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>

Идеи (el = [el].pop()) и try/finally взяты из здесь , хотя, похоже, они тоже не помогают - по понятным причинам, поскольку они предназначены только для исправления ie6.

Я также экспериментировал с использованием addEventListener и методов onmouseover для добавления событий. Единственный способ предотвратить увеличение памяти - это закомментировать обе строки кода.

Ответы [ 3 ]

2 голосов
/ 17 декабря 2010

fn - это закрытие, даже если в нем нет кода. Например. попробуйте отладку с Firebug и установите точку останова внутри этой функции. Все переменные, определенные в замыкании (fn code + переменные, которые висят вокруг = замыкание) теоретически доступны (хотя я не знаю, как получить к ним доступ на практике).

1 голос
/ 29 января 2009

Утечки памяти, связанные с обработчиками событий, вообще говоря, связаны с корпусами. Другими словами, присоединение функции к обработчику событий, который указывает на его элемент, также может предотвратить сборщик мусора в браузерах. (К счастью, большинство новых браузеров «научились хитрости» и больше не теряют память в этом сценарии, но существует множество старых браузеров, плавающих вокруг!)

Такой корпус может выглядеть так:

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);

Тот факт, что fnOver и fnOut обращаются к своей области охвата для ссылки el, - это то, что создает корпус (два, фактически - по одному для каждой функции) и может вызвать утечку браузеров. Ваш код не делает ничего подобного, поэтому не создает вложения, поэтому не должен вызывать утечку (с хорошим поведением) браузера.

Полагаю, это всего лишь одна из неприятностей бета-версии программного обеспечения. : -)

1 голос
/ 29 января 2009

Ну, я совсем не так , и я не могу повторить поведение, поэтому все, что я могу вам сказать, это проблема с памятью, которая может возникнуть из-за какой-либо находится в функции fn, и если это не замыкание, вы должны определять fn вне функции createEl и просто ссылаться на него внутри, поэтому в памяти существует только один экземпляр этого.

Вам нужно лучше обрабатывать привязку к событию (это небезопасно для xbrowser - на данный момент я не решаюсь предложить jQuery), и все это (el =[el]).pop() пахнет мне вуду, хотя я рад, что меня исправили если кто-то может точно объяснить, чего он добивается.

...