Утечка памяти в JQuery? - PullRequest
       1

Утечка памяти в JQuery?

0 голосов
/ 01 марта 2012

В моем приложении есть главная страница с несколькими панелями (DIV), заполненными вызовами AJAX.

HTML

<html>
<head>
    <title>jQuery test</title>
    <script type="text/javascript" src="js/jquery-1.7.1.js"></script>
    <script type="text/javascript" src="js/ago.js"></script>
</head>
<body>
    <input type="button" value="Start 1" onclick="menuAnagReferenti()"/>
    <div id="cmp-area">cmp-area</div>
</body>
</html>

ago.js

function menuAnagReferenti ()
{
    $.ajax({
        url: "./html/fromServer.html",
        cache: false,
        async: false,
        dataType: "html",
        success: function(data) {
            $('#cmp-area').empty();
            $('#cmp-area').append(data);
        }//success
    });
}//end

menuAnagReferenti () в этом примере - это функция, используемая для заполнения панели cmp-области содержимым, полученным с сервера.

Я заметил, что каждый раз, когда я запускаю этот код (я использую IE8 для теста), память всегда увеличивается.Работа в таком режиме в течение длительного времени приводит к ухудшению производительности всего приложения: через некоторое время браузер перестает отвечать на запросы!

После нескольких тестов кажется, что проблема заключается в получении контента с сервера.

Этот контент представляет собой HTML с небольшим количеством кода Javascript внутри большую часть времени.

Если в этом HTML нет javascript, увеличение памяти не происходит!

В случае, если HTML содержит некоторый javascript (даже очень короткий), увеличение памяти все еще может произойти.

Не могли бы вы помочь мне понять, в чем проблема?Что-то не так в моем коде, который генерирует эту проблему?

Спасибо за вашу помощь!

Добавлено 2 марта 2012 г. --------

спасибо Кевину: в моих тестах кажется, что ЛЮБОЙ javascript порождает проблему: более сложный код javascript и память растут быстрее.

спасибо Кори: я не знаю, как использовать ваши предложения в моем случае ... ЯЯ использую JQuery 1.7.1

1 Ответ

0 голосов
/ 01 марта 2012

Вот ответ из другой ветки:

Я думал, что Дэвид может быть на что-то с предполагаемой утечкой removeChild, но я не могу воспроизвести это в IE8 ... это может случиться в более ранних браузерах, ноэто не то, что мы имеем здесь.Если я удаляю вручную div'ы, утечки нет;если я изменю jQuery, чтобы использовать externalHTML = '' (или move-to-bin, а затем bin.innerHTML) вместо removeChild, все равно будет утечка.

В процессе устранения я начал взламывать биты удаленияв jQuery.строка 1244 в 1.3.2:

//jQuery.event.remove(this);
jQuery.removeData(this);

Закомментирование этой строки не привело к утечке.

Итак, давайте посмотрим на event.remove, он вызывает данные («события»), чтобы увидетьесли есть какие-либо события, связанные с элементом.Что делают данные?

// Compute a unique ID for the element
if ( !id )
    id = elem[ expando ] = ++uuid;

Ох.Таким образом, он добавляет одно из свойств взлома записи uUid-to-data-lookup в jQuery для каждого элемента, на котором он даже пытается прочитать данные, включая каждого потомка удаляемого элемента!Как глупо.Я могу замкнуть это, поместив эту строку прямо перед ней:

// Don't create ID/lookup if we're only reading non-present data
if (!id && data===undefined)
    return undefined;

, которая, по-видимому, исправляет утечку для этого случая в IE8.Не могу гарантировать, что это не сломает что-то еще в лабиринте, который является jQuery, но логически это имеет смысл.

Насколько я могу понять, утечка - это просто jQuery.cache Объект (который являетсяхранилище данных, а не кеш как таковой) становится все больше и больше по мере добавления нового ключа для каждого удаленного элемента.Несмотря на то, что removeData должен удалить эти записи в кэше, ОК, похоже, IE не восстанавливает пространство при delete ключе от Object.

(В любом случае, это пример такого рода поведения jQuery Iне ценю. Он делает слишком много под капотом для того, что должно быть тривиально простой операцией ... некоторые из которых довольно сомнительны. Все это с расширением и тем, что jQuery делает с innerHTML через регулярное выражение, чтобы предотвратить это.показ в качестве атрибута в IE просто испорчен и уродлив. А привычка делать геттер и сеттер одной и той же функцией сбивает с толку и, в данном случае, приводит к ошибке.)

[Странно, оставляя утечку для расширенногопериоды времени заканчивались тем, что время от времени приводили к совершенно ложным ошибкам в jquery.js до того, как память фактически закончилась ... было что-то вроде «неожиданной команды», и я заметил, что «имя_узла ноль или нет объекта» в строке 667,насколько я вижу, не следовало даже бежать, не говоря уже о том, что есть чеck там для nodeName, являющегося нулевым!IE не дает мне много уверенности здесь ...]

...