Устранение проблем с памятью

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

  • Узнайте, какой объем памяти используется вашей страницей в диспетчере задач браузера Microsoft Edge.
  • Визуализируйте использование памяти с течением времени с помощью средства "Память ".
  • Определите отсоединяемые деревья DOM (распространенная причина утечки памяти) с помощью snapshot Куча.
  • Узнайте, когда выделяется новая память в куче JavaScript (кучи JS) с помощью инструментирования выделения на временная шкала.

См. также отладку утечек памяти DOM с помощью инструмента "Отсоединенные элементы".

Обзор

В духе модели производительности RAIL основное внимание должно уделяться вашим пользователям.

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

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

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

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

Раздутие памяти: сколько "слишком много"?

Утечку памяти легко определить. Если сайт постепенно использует все больше и больше памяти, значит, у вас есть утечка. Но раздутие памяти немного сложнее закрепить. Что квалифисируется как "использование слишком большого объема памяти"?

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

Здесь важно использовать модель RAIL и сосредоточиться на пользователях. Узнайте, какие устройства популярны среди пользователей, а затем протестируйте страницу на этих устройствах. Если взаимодействие постоянно плохое, страница может превысить возможности памяти этих устройств.

Мониторинг использования памяти в режиме реального времени с помощью диспетчера задач браузера Microsoft Edge

Используйте диспетчер задач браузера Microsoft Edge в качестве отправной точки для исследования проблем с памятью. Диспетчер задач браузера Microsoft Edge — это монитор в реальном времени, который сообщает, сколько памяти использует страница в данный момент.

  1. Нажмите клавиши SHIFT+ESC или перейдите в меню Microsoft Edge main и выберите Дополнительные инструменты>Диспетчер задач браузера, чтобы открыть диспетчер задач браузера Microsoft Edge.

    Открытие диспетчера задач браузера Microsoft Edge

  2. Щелкните правой кнопкой мыши заголовок таблицы диспетчера задач браузера Microsoft Edge и включите память JavaScript.

    Включение памяти JavaScript

Эти два столбца по-разному сообщают о том, как ваша страница использует память:

  • Столбец Память представляет собственную память. Узлы DOM хранятся в собственной памяти. Если это значение увеличивается, создаются узлы DOM.

  • Столбец Память JavaScript представляет кучу JS. Этот столбец содержит два значения. Интересующее вас значение — это живой номер (число в скобках). Динамическое число показывает, сколько памяти используют доступные объекты на странице. Если это число увеличивается, создаются новые объекты или растут существующие объекты.

Визуализация утечек памяти с помощью средства "Производительность"

Вы также можете использовать средство "Производительность " в качестве еще одной отправной точки в исследовании. Средство "Производительность " помогает визуализировать использование памяти страницы с течением времени.

  1. В средствах разработки откройте средство Производительность .

  2. Установите флажок Память .

  3. Сделать запись.

Рекомендуется начинать и завершать запись принудительной сборкой мусора. Чтобы принудительная сборка мусора, нажмите кнопку сборки мусора при принудительном сборе мусора во время записи.

Чтобы продемонстрировать записи памяти, рассмотрите следующий код:

var x = [];
function grow() {
    for (var i = 0; i < 10000; i++) {
        document.body.appendChild(document.createElement('div'));
    }
    x.push(new Array(1000000).join('x'));
}
document.getElementById('grow').addEventListener('click', grow);

При каждом нажатии кнопки, на которую ссылается код, к тексту документа добавляется 10 000 div узлов, а в массив помещается x строка из 1000 000 x символов. При выполнении предыдущего примера кода в средстве производительности создается запись, как показано на следующем рисунке:

Простой рост

Во-первых, объяснение пользовательского интерфейса. Диаграмма HEAP в области Обзор (под NET) представляет кучу JS. Под панелью Обзор находится панель Счетчик . Использование памяти разбивается по куче JS (аналогично диаграмме HEAP в области обзор ), документам, узлам DOM, прослушивателям и памяти GPU. Снимите флажок, чтобы скрыть его от графа.

Теперь анализ кода сравнивается с предыдущим рисунком. Если вы просмотрите счетчик узла (зеленый график), он будет точно совпадать с кодом. Число узлов увеличивается в дискретных шагах. Можно предположить, что каждое увеличение числа узлов является вызовом grow().

Диаграмма кучи JS (синий граф) не так проста. В соответствии с рекомендациями первым падением на самом деле является принудительная сборка мусора (нажмите кнопку сборки мусорапринудительной сборки мусора ).

По мере выполнения записи отображаются пики размера кучи JS. Это естественно и ожидаемо: код JavaScript создает узлы DOM при каждой нажатии кнопки и выполняет большую работу при создании строки из миллиона символов.

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

Обнаружение отсоединяемых утечек памяти дерева DOM с помощью моментальных снимков кучи

Узел DOM собирается только при отсутствии ссылок на узел из дерева DOM или кода JavaScript, выполняемого на странице. При удалении из дерева DOM узел считается "отсоединяется", но некоторые javaScript по-прежнему ссылаются на него. Отсоединяемые узлы DOM являются распространенной причиной утечек памяти.

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

Ниже приведен простой пример отсоединяемых узлов DOM:

var detachedTree;

function create() {
    var ul = document.createElement('ul');
    for (var i = 0; i < 10; i++) {
        var li = document.createElement('li');
        ul.appendChild(li);
    }
    detachedTree = ul;
}
document.getElementById('create').addEventListener('click', create);

При нажатии кнопки, указанной в коде, создается узел с десятью ulli дочерними элементами. На узлы ссылается код, но они не существуют в дереве DOM, поэтому каждый узел отсоединяется.

Моментальные снимки кучи — это один из способов идентификации отсоединяемых узлов. Как следует из названия, моментальные снимки кучи показывают, как память распределяется между объектами JS и узлами DOM для страницы в момент snapshot.

Чтобы создать snapshot, выполните приведенные далее действия.

  1. Откройте DevTools и перейдите к средству "Память ".

  2. Нажмите переключатель Куча snapshot, а затем нажмите кнопку Принять snapshot в нижней части средства.

    Получение кучи snapshot

    Обработка и загрузка snapshot может занять некоторое время.

  3. После завершения snapshot выберите его на панели слева (он называется HEAP SNAPSHOTS).

  4. В текстовом поле Фильтр классов введите Detached, чтобы найти отсоединяемые деревья DOM:

    Фильтрация по отсоединяющимся узлам

  5. Разверните караты, чтобы исследовать отдельное дерево:

    Исследование отсоединяемого дерева

  6. Щелкните узел, чтобы исследовать его дальше.

    В области Объекты можно просмотреть дополнительные сведения о коде, который ссылается на узел. Например, на следующем рисунке detachedTree переменная ссылается на узел.

  7. Чтобы устранить конкретную утечку памяти, изучите код, использующий detachedTree переменную, и убедитесь, что ссылка на узел удаляется, когда она больше не нужна.

Исследование узла

Выявление утечек памяти кучи JS с помощью инструментирования выделения на временная шкала

Инструментирование выделения на временная шкала — это еще одно средство, которое может помочь вам отслеживать утечки памяти в куче JS.

Продемонстрировать инструментирование выделения на временная шкала с помощью следующего кода:

var x = [];
function grow() {
    x.push(new Array(1000000).join('x'));
}
document.getElementById('grow').addEventListener('click', grow);

При каждом нажатии кнопки, на которую ссылается код, в массив добавляется x строка из миллиона символов.

Чтобы записать инструментирование выделения на временная шкала:

  1. Откройте DevTools и выберите средство "Память ".

  2. Щелкните переключатель Инструментирование выделения на временная шкала, а затем нажмите кнопку Пуск.

  3. Выполните действие, которое, как вы подозреваете, вызывает утечку памяти.

  4. По завершении нажмите кнопку Остановить запись кучи, чтобы остановить запись.

  5. При записи обратите внимание, отображаются ли синие полосы на инструментировании выделения на временная шкала, как показано на следующем рисунке:

    Новые выделения

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

  6. Увеличьте масштаб панели, чтобы отфильтровать область конструктора , чтобы отобразить только объекты, выделенные в течение указанного периода времени.

    Масштаб распределения временная шкала

  7. Разверните объект и выберите значение, чтобы просмотреть дополнительные сведения в области Объект .

    Например, на следующем рисунке в сведениях о новом выделенном объекте указывается, что он был выделен переменной xWindow в область:

Сведения об объекте

Исследование выделения памяти по функциям

Используйте тип профилирования выборки выделения для просмотра выделения памяти с помощью функции JavaScript.

Выборка выделения записей

  1. Нажмите переключатель Выборка выделения .

  2. Если на странице есть рабочая роль, ее можно выбрать в качестве целевого объекта профилирования с помощью раскрывающегося меню рядом с кнопкой Пуск .

  3. Нажмите кнопку Пуск .

  4. На веб-странице выполните действия, которые нужно исследовать.

  5. Нажмите кнопку Остановить , когда все действия будут завершены.

DevTools показывает разбивку распределения памяти по функциям. По умолчанию используется представление Heavy (Bottom Up), в котором отображаются функции, которые выделяют большую часть памяти в верхней части.

Выборка выделения

Уменьшение мусора с помощью дополнительных параметров для выборки выделения

По умолчанию тип профилирования выборки выделения сообщает только о выделениях, которые по-прежнему активны в конце сеанса записи. Объекты, которые создаются, удаляются, а затем собираются мусором (GC'd), не отображаются в средстве "Память" при профилировании с помощью выборки выделения или инструментирования выделения для типов временная шкала.

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

Операция сборки мусора, показанная в средстве

Уменьшая объем мусора, создаваемого кодом, вы можете снизить затраты на каждую отдельную сборку мусора и количество операций сборки мусора. Чтобы отслеживать объекты, отбрасываемые GC, настройте тип профилирования выборки выделения с параметрами.

  1. Нажмите кнопку Выборка выделения .

  2. Выберите параметры Включить объекты, отброшенные основными сборками мусора , и Включить объекты, отброшенные дополнительными объектами сборки мусора .

    Параметры сборки выборки выделения

  3. Нажмите кнопку Пуск .

  4. На веб-странице выполните действия, которые нужно исследовать.

  5. Нажмите кнопку Остановить , когда все действия будут завершены.

DevTools теперь отслеживает все объекты, которые были GC во время записи. Используйте эти параметры, чтобы понять, сколько мусора генерируется веб-сайтом или приложением. Данные, передаваемые выборкой выделения , помогут определить функции, которые создают больше всего мусора.

Если вы исследуете объекты, которые были только GC во время определенных крупных или незначительных операций сборки мусора, настройте параметры соответствующим образом, чтобы отслеживать нужную операцию. Дополнительные сведения о различиях между основными и дополнительными сборками мусора см. в статье Мусорное обсуждение: сборщик мусора Orinoco | Блог разработчика обработчика JavaScript версии 8.

Обнаружить частые сборки мусора

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

Для обнаружения частой сборки мусора можно использовать либо диспетчер задач браузера Microsoft Edge, либо записи памяти производительности.

  • В диспетчере задач браузера Microsoft Edge часто растущие и выпадающие значения памяти или памяти JavaScript представляют собой частую сборку мусора.

  • В записях производительности частые изменения (рост и падение) в диаграммах кучи JS или числа узлов указывают на частую сборку мусора.

Определив проблему, можно использовать инструментирование выделения для записи временная шкала, чтобы узнать, где выделяется память и какие функции вызывают выделение.

Примечание.

Некоторые части этой страницы представляют собой измененные материалы, созданные и предоставленные корпорацией Google. Их использование регулируется условиями, описанными в лицензии Creative Commons Attribution 4.0 International License. Исходная страница находится здесь и автор Kayce Basques (Технический писатель, Chrome DevTools & Lighthouse).

Creative Commons License Эта работа лицензируется по международной лицензии Creative Commons Attribution 4.0.