Утечка памяти в javascript при использовании нового Image () - PullRequest
2 голосов
/ 25 сентября 2011

Кажется, у меня утечка памяти, вызванная использованием 'new Image ()' в скрипте javascript. Если я просматриваю используемую физическую память в мониторе ресурсов Windows, то получаю ожидаемое увеличение используемой памяти при загрузке страницы, потому что она загружает некоторые довольно большие изображения, используя следующее:

var imgObjs = [];

// in for loop i = 0, 1, 2...
imgObjs[i] = new Image();
imgObjs[i].onload = function(event) {
    // image loaded
}
imgObjs[this.img_src].src = this.img_src;

Хотелось бы, однако, чтобы при удалении страницы от нее автоматически уничтожались ссылки и освобождалась память, но, похоже, это не так. Вместо этого я ухожу, а затем возвращаюсь на страницу, только обнаружив, что память увеличивается еще больше, так как она загружает изображения снова, не освобождая ранее выделенную память. Я попытался вручную удалить ссылки, поместив код в событие unload, чтобы сделать это, но, похоже, это не имеет никакого значения. Все переменные были первоначально объявлены с помощью 'var':

// allow garbage collection by removing references
$(window).unload(function() {
    for(var i in imgObjs) {
    imgObjs[i] = null;
    delete imgObjs[i];
}
delete imgObjs

// delete other variables that reference the images
});

У кого-нибудь есть указания на то, где я здесь ошибаюсь? Я думал, что проблема может быть связана с циклическими ссылками, так как я создал класс списка, где каждый элемент содержит ссылку на предыдущее и следующее изображение, но я решил, что это следующим образом:

delete galleries[i].pictures.Items[j].prev;
delete galleries[i].pictures.Items[j].next;

1 Ответ

10 голосов
/ 25 сентября 2011

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

В некоторых старых браузерах происходит утечка, если между DOM <==> JS есть циклические ссылки, где некоторый javascript ссылается на элемент DOM, а пользовательский атрибут в элементе DOM ссылается на тот же объект javacript, но это не кажется, что у вас здесь.

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

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

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

Третий выключен, оператор delete предназначен для удаления свойств из объекта. Это все для чего. Смотрите эти статьи: Понимание Удалить и MDN Удалить для более подробного объяснения. Итак, ваш код очистки в обработчике выгрузки неправильно использует delete. Вы не можете удалить переменные или элементы массива с delete. Хотя я не вижу никакой причины, почему этот код необходим, если бы он у вас был, он был бы таким:

// allow garbage collection by removing references
$(window).unload(function() {
    for (var i = 0; i < imgObjs.length; i++) {
        imgObjs[i] = null;
    }
    imgObjs = null;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...