Утечка памяти в IE из-за ссылок на элементы DOM в замыканиях? - PullRequest
2 голосов
/ 19 апреля 2011

Во время недавнего интервью меня спросили: «Чем опасно использование замыканий при обращении к элементам DOM, как это делает этот код?»

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

По-видимому, незаметно для меня приведенный выше код создает памятьтечь в IE.Данное обоснование было довольно расплывчатым, и я его не понял, но, видимо, это может относиться только к более старым версиям IE?

Кто-нибудь может уточнить это?

Ответы [ 2 ]

5 голосов
/ 19 апреля 2011

Сборщик мусора, используемый в кишках IE для работы с памятью, выделенной для / для DOM, не имеет представления о том, как освободить память, которая может свисать, выделенную движком JScript.Таким образом, он просто игнорирует такие вещи.

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

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

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

Теперь, когда переменная "hoHumWhwhat" сохраняется в замыкании.Когда страница перезагружается или DOM изменяется таким образом, что элемент выбрасывается, сборщик мусора DOM не сможет ничего сделать с атрибутом, указывающим на память, принадлежащую JScript.JScript, с другой стороны, не знает, что узел DOM был освобожден, поэтому он считает, что память закрытия все еще используется.

Я допускаю, что в некоторых деталях это может быть неточным, но это основнойпроблема.Об этом писали разные люди, в том числе мистер Крокфорд и (я думаю) ppk в quirksmode.

edit - После более тщательного перечитывания кода, который вы опубликовали, яподумайте, что может быть примером подобного, но противоположного случая: маленькая функция возвращает ссылку на часть значения DOM, поэтому, возможно, кто-то говорит, что JScript будет зависать в памяти DOM (вместоVersa).Теперь, в данном конкретном случае, я немного сомневаюсь, потому что я не вижу, как что-либо «ускользает» от этого замыкания, кроме простой ссылки на атрибут DOM, который должен быть экземпляром примитивной строки и поэтому действительно не долженне вызывает проблемы.Однако эти вопросы могут быть обманчивыми, поэтому я просто сижу здесь и чешу голову.

4 голосов
/ 19 апреля 2011

Следующий код не создает никаких замыканий (см. Ниже) или утечек памяти.

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

Небольшое исследование IE 6 показывает, что код не создает утечку памяти. Я добавил 1000 дивы с большой плитой Lorem Ipsum и уникальных идентификаторов, а затем побежал 1000 анонимных функций в коде выше и каждый раз, когда я освежил страницу упрямо возвращается в памяти использовать это было прежде, чем я открыл стр. Даже добавление на страницу еще нескольких тысяч элементов размером более 100 МБ не беспокоило ее, IE продолжал возвращаться к исходному размеру.

Так что это либо вопрос с подвохом (т. Е. Правильный ответ: «Нет постоянного закрытия и нет циклической ссылки, поэтому нет утечки памяти»), либо тот, кто придумал это, написал не правильно.

Если это не хитрый вопрос, посмотрите, сможете ли вы получить того, кто его написал или задал вопрос, чтобы дать вам демонстрацию этого в действии.

Закрытие

Простое объяснение Закрытия: что ECMAScript позволяет внутренний функции; определения функций и функциональные выражения, которые находятся внутри функции предвещают другие функции. И что эти внутренние функции разрешен доступ ко всем местным переменные, параметры и объявленные внутренние функции в их внешнем Функция (ы). Закрытие образуется, когда одна из этих внутренних функций выполнена доступны вне функции в который он содержал, чтобы он мог исполняться после внешней функции вернулся. На каком этапе это все еще имеет доступ к локальным переменным, параметры и внутренняя функция объявления его внешней функции. Эти локальные переменные, параметр и объявления функций (изначально) имеют ценности, которые они имели, когда внешняя функция возвращена и может быть взаимодействует с внутренней функцией.

Ричард Корнфорд и др., " Javascript Closures ", http://www.jibbering.com/faq/notes/closures/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...