Оптимізація споживання оперативної пам'яті мобільного додатку
Мобільні додатки часто завершуються через нестачу пам'яті. iOS непомітно вивантажує додатки, дані користувача втрачаються, сесія скидається. Android генерує onLowMemory, але якщо не реагувати — процес вмирає. Ми стикаємося з цим щодня і знаємо, як перетворити ненажерливий APK на економний додаток. За 7 років ми провели аудит пам'яті більш ніж 20 проектів — від простих CRUD до складних медіаплеєрів. Знижуємо споживання RAM на 30–50% без зміни функціональності. Замовте аудит — отримайте конкретні рекомендації та готовий план оптимізації.
Як знайти витік пам'яті на Android?
Android Memory Profiler в Android Studio — обов'язковий інструмент. Знімаємо heap dump, сортуємо за retained size, шукаємо несподівано великі об'єкти або класи, яких має бути кілька, а їх тисячі. LeakCanary автоматично знаходить витоки в debug-збірці — вмикаємо його в CI і отримуємо сповіщення на кожен білд. Він детектує витоки в 5 разів швидше ручного аналізу.
Bitmap — головний пожирач. Навіть з Glide або Coil важливо вказувати розмір: override(width, height) для ImageView. Повнорозмірний 2048×2048 для аватарки 48dp — це 16 МБ даремно. Використовуйте downsampling: Glide.with(this).load(url).override(100, 100).into(imageView).
Fragment/Activity — класика через анонімні класи. Handler, Runnable, лямбди із захопленням this тримають посилання після знищення. LeakCanary показує точний ланцюжок.
ViewModel з невідписаними Flow. collectAsStateWithLifecycle вирішує проблему. Без нього — Job.cancel() в onDestroy.
RecyclerView — використовуйте Paging 3. Adapter не тримає повний список у пам'яті, підвантажує порціями.
Чому iOS вбиває додаток?
Xcode Memory Graph Debugger візуалізує retain cycles. Instruments → Allocations відстежує зростання пам'яті. Основні причини:
- Retain cycles в closure.
[weak self]— необхідність для замикань, які живуть довше функції. Особливо підступні ланцюжки: ViewModel → Closure → ViewController → ViewModel. - NSCache без лімітів. Задавайте
countLimitіtotalCostLimit, інакше кеш виросте до сотень МБ. - Зображення — не використовуйте
UIImage(named:)для великих картинок.UIImage(contentsOfFile:)не кешує. Для downsampling застосовуйтеImageIOзkCGImageSourceShouldCacheImmediately = false. - NotificationCenter —
removeObserverв deinit обов'язковий. З iOS 9+ block-based observers самоочищаються, але selector-based — ні.
Що робити з Flutter і React Native?
Flutter: витоки через StreamSubscription без cancel() і AnimationController без dispose(). Dart DevTools → Memory показує граф об'єктів. Кожне перестворення віджета додає нову підписку.
React Native: навігація з react-navigation — увімкніть unmountOnBlur: true для важких екранів. Flipper з Memory plugin аналізує нативну пам'ять окремо від JS heap.
Як виконується аудит пам'яті? Покроково
- Зустріч і збір даних. Дізнаємося архітектуру, сценарії використання, типові дії користувача. Домовляємося про тестові пристрої.
- Базове профілювання. Запускаємо Android Profiler / Xcode Instruments на «чистому» додатку — фіксуємо цифри.
- Стрес-тест. Імітуємо тривалу роботу: відкриваємо 10 разів екран, прокручуємо списки, завантажуємо зображення. Знімаємо heap dump у піку.
- Аналіз. Використовуємо MAT (Android) або Memory Graph Debugger (iOS) для пошуку retain cycles, надлишкових кешів, бітмапів. Складаємо звіт з 20+ метриками.
- Правки. Виправляємо код, оптимізуємо кеші, додаємо downsampling. На CI налаштовуємо автоматичні перевірки на регресію.
Процес займає від 3 робочих днів (діагностика) до 3 тижнів (повна оптимізація). Отримайте консультацію — оцінимо ваш проект.
Процес оптимізації
| Етап | Інструмент | Мета |
|---|---|---|
| Замір базового споживання | Android Profiler / Xcode Instruments | Зафіксувати поточні цифри |
| Аналіз heap dump | MAT (Android) / Memory Graph (iOS) | Знайти retain cycles та несподівані утримання |
| Стрес-тестування | Monkey / XCUITest | Виявити витоки при тривалій роботі |
| CI інтеграція | LeakCanary / Instruments | Не допустити регресію |
Цільові значення: простий CRUD — 50-80 МБ, медіаплеєр — 150-200 МБ.
Таблиця: порівняння інструментів
| Інструмент | Платформа | Автоматизація | Швидкість аналізу |
|---|---|---|---|
| LeakCanary | Android | + | Миттєво |
| Memory Graph Debugger | iOS | - (ручний) | Секунди |
| Instruments | iOS | + (шаблони) | Хвилини |
| Dart DevTools | Flutter | + | Реальний час |
Що входить у роботу
- Діагностика: профілювання на реальних пристроях, вивантаження heap dump, звіт з 20+ метриками.
- Виправлення коду: рефакторинг retain cycles, оптимізація кешів, downsampling зображень.
- Налаштування CI: інтеграція LeakCanary, автоматичні сповіщення при регресії.
- Навчання команди: розбір знайдених проблем, чек-лист best practices.
- Гарантія: фіксована ціна і терміни, пост-аудит через місяць після впровадження.
Строки та вартість
Діагностика — від 3 робочих днів. Повна оптимізація — 1-3 тижні залежно від об'єму коду. Вартість визначається після аналізу вашого проекту. Економія на підтримці та інфраструктурі може бути значною. Зв'яжіться з нами для оцінки вашого проекту.
Для довідки: Apple Memory Management і Android Memory Overview містять детальні рекомендації.







