Ответ
Garbage Collector (GC) в Android работает с кучей (Heap) — областью памяти, где хранятся объекты, созданные во время выполнения приложения. Он автоматически освобождает память, удаляя объекты, на которые нет активных ссылок.
Особенности:
- Young Generation (Eden, Survivor spaces) — для краткоживущих объектов.
- Old Generation — для долгоживущих объектов.
- Permanent Generation (до Android 5.0) — метаданные классов (заменена на ART с компактирующим GC).
Пример утечки:
class LeakyActivity : Activity() {
private val leak = staticList // Статическое поле держит ссылку на Activity
companion object {
val staticList = mutableListOf<Any>()
}
}
Решение: избегать статических ссылок на контекст/View.
Ответ 18+ 🔞
Давай разберёмся с этим мусорщиком, а то у некоторых он в голове, а тут в андроиде. Ну, Garbage Collector, он же GC — это такой дворник в твоей оперативке. Сидит себе, курит, а как видит, что какой-то объект болтается без дела, на который никто не ссылается, — ёпта, сразу в мусорку его. Место освобождает. Всё происходит в куче (Heap) — это типа общага, где все твои объекты живут.
Как он там хозяйничает:
- Молодёжь (Young Generation: Eden, Survivor spaces) — сюда попадают все новобранцы, объекты-однодневки. Пожили чуток, если никому не пригодились — в пизду, на выход. Выжившие переезжают.
- Старики (Old Generation) — сюда попадают те, кто зацепился, выжил. Живут долго, но если и тут на них все забили — пизда рулю, и их убирают.
- Постоянное поколение (Permanent Generation, но это старьё) — раньше тут метаданные классов лежали. Сейчас, ядрана вошь, в ART всё по-другому, с компактирующим сборщиком, чтобы память фрагментирована не была.
А теперь главный прикол, где все и обламываются. Смотри, классическая утечка, доверия ебать ноль к таким кодерам:
class LeakyActivity : Activity() {
private val leak = staticList // Вот эта хуйня! Статик поле держит ссылку на всю Activity!
companion object {
val staticList = mutableListOf<Any>() // И этот список живёт вечно!
}
}
Что происходит? Активность должна умереть, но статический список staticList — он же живёт, пока живёт класс. А в нём ссылка на leak, который ссылается на внешний класс LeakyActivity. И получается, что на твою активность есть живая, неубиваемая ссылка из статического контекста. Сборщик мусора подходит, смотрит — а, хуй с горы, ссылка есть, не трогаю. И память не освобождается. Активность накрылась медным тазом, но в памяти висит мёртвым грузом.
Решение, блядь, проще некуда: не пихай статические ссылки на контекст, вьюхи или сами активности. Вообще. Если очень надо — используй слабые ссылки (WeakReference), но лучше архитектуру пересмотреть. А то потом приложение жрёт память как не в себя, а ты гадаешь, какого хуя.