Проблемы поиска утечки памяти в веб-приложении с помощью Chrome DevTools

Браузер Google Chrome поставляется с превосходными инструментами для разработчика, они же есть в Яндекс.Браузере, новой Опере, и в других браузерах, основанных на базе Chromium.

Среди них есть потрясающие инструменты для работы с памятью, ознакомиться с которыми можно в статье пользователя Panya«Как находить и устранять утечки памяти на примере Яндекс.Почты».

Javascript хранит объект в памяти до тех пор, пока на него есть хоть одна ссылка. Как только вы удаляете все ссылки на объект, он уничтожается сборщиком мусора.

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

Это кажется очень простым, но есть несколько достаточно неожиданных «мест» где могут храниться ссылки на объекты, тем самым задерживая их удаление, и создавая утечку памяти.

1. Консольный вывод.




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

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

2. Включенные экспериментальные функции браузера.




В моем случае это были «JavaScript frameworks debugging» и «Support asynchronous call stacks», которая уже вышла из экспериментальных.

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

Когда я снял галочки, проблемы исчезли.

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

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

3. Расширения браузера.




В моем случае это был Batarang. Это инструмент для отладки приложений, построенных на AngularJS, и он у себя внутри сохраняет ссылки на scope приложения, что создавало утечку памяти.

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

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

4. Функция «Record Heap Allocations».




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

Первое — функция показывает не только сколько памяти откладывается, но и сколько освобождается («свободная» память становится светло-серой), при этом показывать может не всегда точно.

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

Для теста я повторял многократно одно действие в приложении, и смотрел, что происходит с памятью.

Record Heap Allocations показывал, что память очищалась не полностью, и после каждого действия оставалось немного занятой памяти, в то время, как Timeline показывал, что все очищается хорошо, и никаких утечек нет.

Второе — не стоит использовать Record Heap Allocations и Timeline одновременно.

Если одновременно включить Record Heap Allocations и Timeline, то Timeline будет показывать, что память течет, то есть используется во все большем и большем объеме.

Если же включить один только Timeline, то память течь не будет, что приводит к выводу, что Record Heap Allocations удерживает ссылки на объекты, а потому непригоден для отслеживания «освобождения» памяти.

Заключение


В статье я привел 4 примера мест, где могут быть сохранены ссылки на объекты, препятствующие их удалению сборщиком мусора.

Естественно, это не все проблемные места, а лишь только те, с которыми столкнулся лично я.

Что-то из этого, возможно, уже исправлено, а что-то, возможно, будет исправлено в будущем.

Важно понимать, что помимо самого разрабатываемого приложения ссылки могут быть сохранены и в других местах, и это следует учитывать при поиске утечек памяти.
  • +18
  • 18.1k
  • 4
Share post

Similar posts

AdBlock has stolen the banner, but banners are not teeth — they will be back

More
Ads

Comments 4

    0
    ох жеж!
    буквально неделю назад использовал для поиска утечек в nodejs париложении.
    в принципе все выглядит точно так же, только чуть-чуть тяжелее заставить работать (webkit-agent + старый вариант devtools).
      0
      А какой основной способ отловки утечек? Timeline? Это же долго — ждать два-три срабатывания сборщика, сравнивать остаток, а потом строить гипотезы об утечках. Record heap allocations?
        +3
        Основным можно назвать Take Heap Snapshot, поскольку в большинстве случаев управиться можно им одним, просто сравнивая разные снапшоты по «Технике трех снапшотов» из статьи «Как находить и устранять утечки памяти на примере Яндекс.Почты».

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

        image

        А Record Heap Allocations больше применим для определения того, какое конкретно действие сколько памяти откладывает.
        +1
        А еще бывает забудешь отключить Preserve log, и DevTools небольшими кусками начинает есть память.

        Only users with full accounts can post comments. Log in, please.