Подтвердить что ты не робот

JavaScript: следует ли беспокоиться о утечке памяти в 2011 году?

Тема утечек памяти в JavaScript часто не возникает. Однако я наткнулся на эту статью, написанную в 2007 году. Авторы заявляют:

Internet Explorer и Mozilla Firefox - это два веб-браузера. обычно связанный с утечками памяти в JavaScript.

Должен ли я по-прежнему беспокоиться о утечке памяти JavaScript в 2011 году? Если да, то о чем я должен быть осторожен?

4b9b3361

Ответ 1

Хороший разработчик javascript будет знать о различных шаблонах дизайна, которые могут привести к утечкам памяти, и вы избегаете кодирования всего, что могло бы привести к утечке почти во все страницы, которые вы кодируете.

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

Практически говоря, утечки являются существенными только в некоторых случаях. Здесь, где я особенно беспокоюсь о них:

  • Что-нибудь, что я делаю повторно на таймере, особенно если его можно продолжать работать в течение длительного времени. Например, если у вас есть слайд-шоу, которое может просто зацикливаться навсегда, вы должны абсолютно убедиться, что ничто в слайд-шоу не является накапливающейся утечкой объектов JS или DOM.
  • Веб-страница, которая работает как приложение, и пользователь может долгое время оставаться на одной странице, взаимодействовать со страницей, делать ajax-вызовы и т.д. Например, приложение для веб-почты может быть открытым и на такой же фактический документ браузера в течение очень долгого времени, делая много и много взаимодействий пользователей и серверов.
  • Веб-страница, которая регулярно создает и уничтожает множество элементов DOM, например, что-то, что регулярно использует ajax для извлечения кучи нового HTML.

Места, где я действительно не беспокоюсь о утечках:

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

Некоторые из ключевых вещей, за которыми я слежу.

  • Любые длительные переменные или свойства JS, содержащие ссылки на элементы DOM при создании/уничтожении элементов DOM.
  • Любые свойства объекта DOM, содержащие ссылки на другие объекты DOM или ссылки на объекты JS, содержащие ссылки на другие объекты DOM (это может создавать циклические ссылки и перекрестные ссылки между JS/DOM, которые могут возникнуть у некоторых старых браузеров).
  • Любые большие структуры данных, которые я загружаю для временного использования. Я уверен, что ссылки на эти большие структуры данных не хранятся.
  • Любые кэши данных. Удостоверьтесь, что ничего действительно большого не кэшируется, что вы не хотите кэшировать. Убедитесь, что все кэши, которые используются повторно, не накапливаются навсегда и имеют какой-то механизм старения, чтобы избавиться от старых объектов.

Ответ 2

Да, утечка памяти, безусловно, является проблемой в JavaScript, поскольку круговые ссылки действительно возможны. Очень распространенным источником утечек памяти является использование закрытий. В качестве примера рассмотрим:

var outerFunction = function(param1, param2, param3) {
     var innerFunction = function() {};
     return innerFunction;
};

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

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

Обратите внимание, что эти проблемы связаны с кодом JavaScript, написанным веб-разработчиками. Утечки памяти в базовых интерпретаторах JavaScript, по возможности, гораздо меньше, и это не то, о чем веб-разработчики могут обоснованно относиться к этому, поскольку это задание авторов браузера.

Ответ 3

НЕТ.

Более полный ответ: может быть. Тот факт, что вы так неопределенно спрашиваете, является сильным сигналом о том, что вам лично вряд ли придется беспокоиться.

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

Есть только несколько вопросов, на которые вам нужно ответить:

Q: Поддерживаете ли вы богатое одностраничное приложение, в котором используется JavaScript?

Если нет, то не тратьте время на беспокойство. Если вы (или ваш QA или ваши клиенты) найдете проблему с избыточным использованием памяти со страницей, тогда исправьте ее, когда она появится.

В: Нужно ли вам поддерживать мобильные устройства, и у вас тяжелое использование javascript?

Мобильные устройства имеют ограниченную память и требуется дополнительная осторожность.

Если, вы разрабатываете тяжелое приложение JavaScript, и вам нужно беспокоиться об использовании памяти, затем...

Проблема "грязных" ссылок на объекты, которые вызывают объекты JavaScript и объекты DOM, чтобы никогда не собирать сбор мусора, важна для определенных типов приложений JavaScript. Кэши, которые растут вечно, неожиданные глобальные ссылки и неожиданные ссылки внутри закрытий, могут быть проблемой.

Инструмент "Снимок кучи" в Chrome Web Inspector может помочь.

Вот проект git, который имеет полезный скрипт и ходит по объектам javascript, которые он может: https://github.com/tlrobinson/leakhelper

Существуют и другие инструменты, которые помогут вам, но со временем я написал свои собственные данные:  1. наши рамки маркируют удаленные виджеты, поэтому я написал код, чтобы ходить по всем массивам и объектам из окна или документа, ища пути к отмеченным объектам (код javascript не может ходить закрытием, но определенно помог найти некоторые утечки).  2. Другим трюком, который я использовал, было то, что когда виджет x был удален, я делаю x.leakhelper = window.createElement('leakhelper') и setAttribute oid виджета, но не добавляю элемент в документ. Если элемент DOM не является сборкой мусора, то виджет должен иметь ссылку на него где-то. В IE используйте window.collectGarbage(), чтобы заставить GC и использовать sIEve для обнаружения просочившегося элемента DOM (я нашел, что sIEve действительно полезен).

Устаревший вопрос: нужно ли вам сильно поддерживать IE6 или IE7? И вы сильно используете JavaScript? Большинство ужасных утечек, которые вы использовали для чтения, происходят только в < IE8. Если вы поддерживаете IE6 или IE7, тогда вам нужна удача и настойчивость (все фреймворки протекают, и сложно писать код, который даже не с идеальной каркасной платформой), я написал свой собственный код предотвращения утечки IE для нашего производства для пользователей IE6/7). Протечки IE6/IE7 могут продолжаться даже после закрытия вашей страницы - вот почему они настолько противны.

Ответ 4

Ну, люди по-прежнему используют старые версии IE. Поэтому будьте осторожны с циркулярными ссылками, потому что IE имеет серьезные проблемы с этим. Я считаю, что распространенная ошибка в этом отношении заключается в ссылке на элемент HTML в закрытии, который находится внутри обработчика события этого элемента. Просто установите переменную, ссылающуюся на элемент, на null, и все будет хорошо.

Ответ 5

Это действительно зависит от 2 вещей -

  • Средняя продолжительность выполнения ожидания вашего приложения. Простой jquery lightbox или carusel на главной странице интернет-магазина может протекать (и часто это происходит, потому что они кодируются так плохо), но никто не заметит (потому что страница закрыта или обновлена ​​в течение нескольких минут или меньше). Но Node.js-сервер, полная социальная сеть ajax, браузерная игра или онлайн-среда IDE - могут работать в течение нескольких часов или даже дней без остановок.

  • сложность ввода/вывода вашего приложения. Чем больше вы касаетесь DOM, XHR/сети, файлов, событий DOM/UI, тем больше времени вы перерисовываете на экране (будь то холст, html или svg) - чем больше риск утечек, тем хуже память (что не является утечкой) и работает в ошибках браузера.

Хорошо для вас - эти две вещи соотносятся друг с другом. Таким образом, вы либо пишете ковш-код, как завтра, или инженер производительности, выносливости и надежности.

p.s.: Если вам нужно поддерживать IE8-, вы еще не в 2011 году. Поэтому вам просто нужно волноваться, как в старые добрые времена.