Использование jQuery и утечек памяти - PullRequest
3 голосов
/ 11 марта 2011

Я использую jQuery уже более пары месяцев и читаю об утечках памяти Javascript в течение нескольких дней. У меня есть два вопроса относительно утечек памяти и jQuery:

  1. Когда я связываю (используя .bind (...)), должен ли я их связывать (.unbind ()), если я покидаю страницу / обновление, чтобы избежать утечек памяти, или jQuery удаляет их для меня?

  2. Что касается замыканий, я прочитал, что они могут привести к утечкам памяти при неправильном использовании. Если я сделаю что-то вроде:

    function doStuff (objects) {// objects - это объект jQuery, который содержит массив объектов DOM var textColor = "red"; objects.each (функция () { $ (this) .css ("color", textColor); }); }

    doStuff ($ ("*"));

Я знаю, что вышеприведенный код глуп (лучше / проще), но я хочу знать, не вызывает ли это проблемы с циклическими ссылками / замыканиями в .each и приведет ли это к утечке памяти. Если это вызывает утечку памяти, как бы я переписал ее (обычно аналогичным способом), чтобы избежать утечки памяти?

Заранее спасибо.

Редактировать: у меня есть еще один случай, похожий на вопрос 2 (который, я думаю, делает эту часть 3).

  1. Если есть что-то вроде этого:

    function doStuff (objects) {// объекты iframe var textColor = "red";

    function innerFunction()
    {          
        $(this).contents().find('a').css("color", textColor );
    }
    
    objects.each(function(){   
        //I can tell if all 3 are running then we 
        //have 3 of the same events on each object, 
        //this is just so see which method works/preferred
    
        //Case 1
        $(this).load(innerFunction);
    
        //Case 2
        $(this).load(function(){
           $(this).contents().find('a').css("color", textColor );
        });
    
        //Case 3  
        $(this).load(function(){
           innerFunction();
        });
    });
    

    }
    doStuff ($ ("iframe"));

Выше приведены 3 случая, и я хотел бы знать, какой метод (или все) вызовет утечку памяти. Также я хотел бы знать, какой метод является предпочтительным (обычно я использую вариант 2) или лучше практиковать (или, если это не хорошо, что будет лучше?).

Еще раз спасибо!

Ответы [ 4 ]

1 голос
/ 11 марта 2011

Есть некоторые тонкие шаблоны утечек, которые вы можете даже не распознать.Проверьте вопрос, который я задавал некоторое время назад о подобной проблеме jQuery 1.5 Утечка памяти в IE8

Если вы создаете замыкание вокруг объекта, который ссылается на узел dom, протекающий цикл ссылоксделано, и, к сожалению, это не может быть исправлено простым снятием привязки.Вам нужно будет установить нулевую ссылку на узел DOM в объекте.

1 голос
/ 11 марта 2011

1) Нет. Браузер очищает все между загрузками страниц.

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

Однако, если вместо .each() у вас было что-то безвредное, например $('div:eq(0)').bind() (я пытаюсь подчеркнуть, что это не обязательно должна быть ссылка на большую переменную objects, достаточно, чтобы это было даже одно несвязанный элемент), так как анонимная функция, отправленная на .bind(), закрывает переменную objects, она останется достижимой и, следовательно, не будет собирать мусор, что допускает утечки памяти.

Простой способ избежать этой проблемы - objects = null; в конце выполнения функции.

Должен заметить, что я не знаком с механизмами сборки мусора JS, поэтому вполне возможно, что существуют разумные интеллектуальные оптимизации. Например, можно проверить, пытается ли анонимная функция получить доступ к любым закрытым переменным, и если нет, она может передать их сборщику мусора, что решит проблему.

Для дальнейшего чтения поищите ссылки на модель памяти javascript, в частности модель окружения и статическое связывание.

0 голосов
/ 11 марта 2011

Около 1, иногда вам приходится освобождать свои ресурсы, особенно если у вас есть циклические ссылки и используется Internet Explorer (из-за некоторых ошибок, потому что теоретически вам не нужно этого делать);) Карты Google имели функцию в своих v2, чтобы предотвратить то, что нам пришлось вызвать на document.onunload (GUnload).

Около 2, у вас нет круговых ссылок. Он потребляет много памяти, так как this должен иметь собственный контекст выполнения для доступа к textColor среди других ..

Циклическая ссылка достигается, когда объект ссылается на себя или замыкание вызывает себя. Может быть, есть другие ситуации ..

Надеюсь, это поможет

0 голосов
/ 11 марта 2011

Что касается 1., нет, вам определенно не нужно .unbind() при выходе со страницы.Я не совсем уверен насчет двух.

...