Ответ
В Dart используется поколенческий (generational) сборщик мусора (Garbage Collector, GC), оптимизированный для интерактивных приложений с коротким временем жизни большинства объектов, что типично для UI во Flutter.
Основные поколения:
-
Молодое поколение (Young Generation / Nursery):
- Сюда попадают все вновь созданные объекты.
- Сборка мусора здесь происходит часто и быстро (Minor GC). Алгоритм — копирующий (copying).
- Объекты, пережившие одну сборку, перемещаются в следующее пространство внутри молодого поколения или в старое.
-
Старое поколение (Old Generation):
- Здесь находятся долгоживущие объекты, пережившие несколько сборок в молодом поколении.
- Сборка происходит реже, но может занимать больше времени (Major GC). Используется алгоритм mark-sweep-compact (пометить-очистить-уплотнить).
Как это влияет на разработку во Flutter:
- Краткосрочные объекты (внутри
build()-методов) дешевы. Они создаются в молодом поколении и быстро утилизируются. - Избегание утечек памяти: Важно удалять подписки (например,
StreamSubscription,Listenable). Несобранные ссылки удерживают объекты в памяти, препятствуя работе GC. - Профилирование: В Dart DevTools можно отслеживать пики использования памяти и активность GC.
Пример, создающий нагрузку на GC:
void inefficientBuild() {
List<String> temporaryList = [];
for (int i = 0; i < 1000; i++) {
temporaryList.add('Item $i'); // Создаются тысячи короткоживущих объектов
}
// После выхода из метода `temporaryList` и все строки становятся мусором,
// что провоцирует частые Minor GC.
}
Лучшая практика: Использование const для виджетов и неизменяемых данных, чтобы уменьшить количество создаваемых объектов и нагрузку на GC.
Ответ 18+ 🔞
Давай разберёмся с этим вашим сборщиком мусора в Dart, а то народ пугается, как чёрт ладана. Система, надо сказать, хитрая, но в целом логичная, если вникнуть.
Представь себе, что память — это такой двухкомнатный общежитийный сортир. Первая комната — молодое поколение. Туда заходят все новенькие объекты, которые только что родились в твоём build()-методе. Там весело, шумно, но уборка (Minor GC) происходит часто и быстро, по принципу «всё, что не прибито гвоздями, — на выход». Выжившие после этой чистки переезжают в соседнюю комнату.
А соседняя комната — это уже старое поколение. Там обитают матёрые, проверенные временем объекты, которые пережили не одну уборку. Уборка здесь (Major GC) случается реже, но зато капитальная: всё перетряхивают, выкидывают хлам и компактно упаковывают. Занимает больше времени, но что поделать.
Как на это всё смотреть в контексте Flutter?
Вот ты пишешь код, и у тебя каждую миллисекунду в build() рождаются и умирают сотни виджетов и строк. Это нормально! Для них эта система — просто рай. Зашёл в первую комнату, быстро пописал на стенку и вышел, а уборщик уже следом подметает. Дешёво и сердито.
Проблемы начинаются, когда ты начинаешь создавать утечки. Это как если гость из первой комнаты привяжет себя верёвкой к батарее в старой. Уборщик придёт, потрогает верёвку — ага, ссылка живая — и пойдёт дальше. А объект так и будет висеть мёртвым грузом, занимая место. Типичный случай — не отписался от StreamSubscription или AnimationController не dispose()нул. Вот это реально доверия ебать ноль к таким разработчикам.
Смотри, вот пример кода, который заставит сборщик матюгаться и потеть:
void inefficientBuild() {
List<String> temporaryList = [];
for (int i = 0; i < 1000; i++) {
temporaryList.add('Item $i'); // Каждую перерисовку создаётся 1000 новых строк!
}
// Метод закончился, список никому не нужен. Вся эта куча объектов — мгновенный мусор.
// GC смотрит на это и говорит: «Ёпта, опять? Да я только присел!»
}
Каждый раз, когда этот метод вызывается (а в Flutter это может быть часто), ты создаёшь овердохуища временных объектов. Молодое поколение забивается быстрее, уборки учащаются, и в какой-то момент может дёрнуться и основная, долгая уборка. А это уже просадка FPS, и пользователь думает, что приложение тормозит.
Так что делать-то?
Главный совет — используй const где только можно. const Text('Привет') — это один объект на всю жизнь приложения. Он создался один раз и поселился в особом, «бессмертном» месте. Никакого мусора, никакой нагрузки на GC. Красота.
И конечно, следи за подписками и контроллерами. Закрывай за собой двери. В общем, не будь распиздяем, и сборщик мусора будет твоим тихим, почти незаметным другом, а не врагом, который постоянно орет «ублюдки, опять насрали!».