tgoop.com/super_oleg_dev/197
Last Update:
Привет!
За недавнее время появилось несколько статей про утечки памяти в JavaScript Closures:
- https://jakearchibald.com/2024/garbage-collection-and-closures/
- https://www.nico.fyi/blog/memory-issue-in-javascript-and-closures
Не знаю, совпадение или я просто начал обращать на это внимание, но приходится много профилировать приложения на утечки и эти замыкания меня буквально преследуют, по большей части ссылки на объекты очищаются, но наконец-то настоящая утечка через замыкание нашлась.
Сначала пару моментов про наши приложения.
На tbank.ru активно используются микрофронтенды и SSR.
Серверный рендеринг с микрофронтами устроен так:
- для каждого микрофронта есть точка входа для Node.js окружения (условно header.server.js)
- сервер скачивает эти скрипты, получает строки с JS кодом
- выполняет строки как JS код в изолированном окружении через vm модуль
- на выходе получает обычные React компоненты
Приложения на tbank.ru построены на нашем фреймворке Tramvai, построенном поверх механизма Dependency Injection.
Особенность этого механизма, что на сервере, на каждый запрос пользователя, создается Dependency Injection контейнер. В этом контейнере хранится все, от объекта запроса до итоговой HTML строки которую мы отдадим в ответ пользователю.
Из-за этой особенности как правило факт утечки найти легко - каждый контейнер может весить несколько мегабайт, при утечке эти контейнеры не будут очищаться через Garbage Collector при завершении запросов.
В данном случае интересен именно механизм утечки и цепочка ссылок до контейнера, который не убирал GC.
На скриншоте профайлера, на самом деле сразу видно всю цепочку, но из-за ее особенностей раскопал причину не сразу.
BY SuperOleg dev notes

Share with your friend now:
tgoop.com/super_oleg_dev/197