Работа мечты в один клик 💼

💭Мечтаешь работать в Сбере, но не хочешь проходить десять кругов HR-собеседований? Теперь это проще, чем когда-либо!
💡AI-интервью за 15 минут – и ты уже на шаг ближе к своей новой работе.
Как получить оффер? 📌 Зарегистрируйся 📌 Пройди AI-интервью 📌 Получи обратную связь сразу же!
HR больше не тянут время – рекрутеры свяжутся с тобой в течение двух дней! 🚀
Реклама. ПАО СБЕРБАНК, ИНН 7707083893. Erid 2VtzquscAwp
Перевод публикуется с сокращениями, автор оригинальной статьи Rafal Kuć.
Вы должны быть уверены, что знаете обо всех пользовательских проблемах, как только они появляются в продакшене, а в идеале, до него. Одной из таких бед являются утечки памяти.
Для отслеживания этих неприятностей можно использовать Sematext Experience – инструмент мониторинга, позволяющий не только контролировать использование веб-приложениями памяти, но также быстро и эффективно обнаруживать утечки. В статье мы подробно рассмотрим, как это делается.

Что такое утечка памяти
Утечка памяти – это избыточное потребление ресурсов из-за неправильного управления распределением памяти в программном обеспечении. Она происходит, когда веб-приложение выделяет память и продолжает использовать ее даже когда та больше не нужна.
Что вызывает утечку памяти: признаки, на которые следует обратить внимание
Веб-приложение будет создавать и использовать различные константы, переменные и функции для выполнения работы. Все они требуют памяти. В JavaScript и других языках программирования высокого уровня, когда ресурс больше не нужен, он будет удален автоматической системой управления памятью, называемой сборщиком мусора.
Во фронтенд-приложениях существует несколько распространенных паттернов, которые могут вызвать утечку памяти. К ним относятся:
- Замыкания – внутренние функции, имеющие ссылки на переменные внешних. Таким образом внутренняя функция не позволяет сборщику мусора освободить память.
- Случайные глобальные переменные – ранее необъявленные переменные станут глобальными и не будут освобождены.
- Несвязанные коллекции – массивы, мапы и наборы позволяют хранить данные в каком-то виде, но с багами в коде они могут привести к утечке памяти из-за вечного хранения ссылок. Такой пример будет рассмотрен ниже.
- Отсоединенный DOM – элемент Document Object Model, который больше не используется, но на него продолжают ссылаться.
- Несвязанные таймеры – работающие вечно и сохраняющие объекты таймеры могут привести к утечке памяти.
Как обнаружить утечки памяти: пример приложения
Чтобы проверить фактическую утечку памяти, создадим простое веб-приложение, имитирующее мониторинг поведения пользователей e-commerce. Страница отслеживает продукты, с которыми пользователи взаимодействуют при просмотре магазина. Каждое показанное объявление, возвращенный товар из поиска и т. д. – все помещается в массив. Код выглядит следующим образом:
function(product, timestamp, page) {
visited.push({product, timestamp, page})
}
Дальнейшая идея заключается в том, чтобы хранить все в бекенде, периодически отправляя данные. Однако чтобы создать утечку, мы забываем сделать одну штуку: после отправки данных в бекенд не очищаем массив. Это означает, что на данные по-прежнему ссылаются из нашего веб-приложения. Если пользователь не закрывает вкладку, данные будут продолжать добавляться, что приведет к утечке памяти.
Теперь посмотрим, как можно идентифицировать возникновение утечки памяти с помощью Sematext и его способности измерять использование памяти сайтом и приложением.
Интеграция Sematext Experience с веб-приложением
Первый шаг – настроить приложение на использование Sematext Browser SDK для отправки данных в облако Sematext.
Для этого добавим скрипт перед закрывающим тегом </head>:
<script type="text/javascript">
(function(e,r,n,t,s){var a=[];e[s]=function(){a.push(arguments)};e[s].queue=a; var o=[];var i=[];var c=true;var p=void 0;if(window.PerformanceObserver&& window.PerformanceObserver.supportedEntryTypes&&( PerformanceObserver.supportedEntryTypes.indexOf("longtask")>=0|| PerformanceObserver.supportedEntryTypes.indexOf("element")>=0)){ p=new PerformanceObserver(function(e){e.getEntries().forEach(function(e){ switch(e.entryType){case"element":i.push(e);break;case"longtask":o.push(e);break; default:break}})});p.observe({entryTypes:["longtask","element"]})}e[s+"lt"]={ longTasks:o,timingElements:i,inPageLoad:c,observer:p};if(t){var u=r.createElement(n); u.async=1;u.src=t;var f=r.getElementsByTagName(n)[0];f.parentNode.insertBefore(u,f)}})
(window,document,"script","//cdn.sematext.com/experience.js","strum");
</script>
Второй шаг зависит от типа вашего веб-приложения и используемого фреймворка – нужно сообщить Browser SDK, как ему себя настроить. Например, для стандартного развертывания нескольких веб-страниц вы бы использовали перед закрывающим тегом </head> что-то вроде этого:
<script type="text/javascript">
strum('config', { token: '<token>', 'receiverUrl': 'https://rum-receiver.sematext.com' });
</script>
Если вы используете какую-либо одностраничную архитектуру, инструкции по установке приложения Sematext Experience помогут выполнить все необходимые для отправки метрик шаги.
Выявление утечки памяти
Зная что делает пользователь, мы можем взглянуть на графики в Sematext Experience. Перейдите к отчету об использовании памяти в приложении:

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

Можно наблюдать скачкообразные сегменты, но в более длительном периоде использование памяти остается между максимумом и минимумом и не растет бесконечно. Мы видим, что в нашем гипотетическом примере e-commerce это не так. Если перейти к просмотру одной сессии, виден постоянный рост использования памяти с менее чем 2 МБ до 12 МБ, и нет никакого падения в течение этого времени. Обычно это означает, что где-то в приложении произошла утечка памяти. Глядя на данные сессии, мы можем видеть загрузку страниц и HTTP-запросы:

Этот экран помогает сузить круг ошибок, показывая все действия пользователя: какие вызовы API были сделаны, какие части приложения выполнялись, какие ресурсы были загружены. Остается только изучить все части кода, и после дальнейшего исследования можно будет найти проблемные фрагменты.
Поддерживаемые браузеры
Возможности измерения памяти Sematext Browser SDK зависят от используемого браузером API для предоставления связанных с памятью метрик. Поддерживается он только в Chrome и проходил испытания Chrome Origin для Chrome 82-87. Начиная с Chrome 89 API будет полностью доступен — это означает, что пользователям потребуется новейший веб-браузер Google.
Заключение
С помощью правильных инструментов выявить проблемы с утечкой памяти довольно просто. Именно для этой цели был создан и постоянно совершенствуется Sematext Experience – он предоставляет вам комплексное, доступное и простое в использовании решение для мониторинга.
Дополнительные материалы:
Комментарии