Оптимізація використання оперативної пам'яті в іграх

Наша компанія з розробки відеоігор веде незалежні проекти, спільно з клієнтом створює ігри та надає додаткові операційні послуги. Досвід нашої команди дозволяє нам охопити всі ігрові платформи та розробити приголомшливий продукт, що відповідає баченню клієнта та перевагам гравців.

Від імерсивних застосунків до ігрових світів і 3D-сцен

Наша виділена команда для VR/AR/MR-розробки, Unity-продакшну і 3D-моделювання та анімації — з власними кейсами і презентаціями.

Відвідати персоналізований сайт
Показано 1 з 1 послугУсі 242 послуг
Оптимізація використання оперативної пам'яті в іграх
Складна
від 2 робочих днів до 2 тижнів
Часті питання

Наші компетенції

Які етапи розробки гри?

Останні роботи

  • image_games_mortal_motors_495_0.webp
    Розробка гри для компанії Mortal Motors
    683
  • image_games_a_turnbased_strategy_game_set_in_a_fantasy_setting_with_fire_and_sword_603_0.webp
    Покрокова стратегія у фентезі сеттингу With Fire And Sword
    862
  • image_games_second_team_604_0.webp
    Розробка ігри для компанії Second term
    491
  • image_games_phoenix_ii_606_0.webp
    3D-анімація – тизер для гри phoenix 2.
    533

Оптимізація використання RAM в іграх

Крах без попередження на пристроях з 3 ГБ RAM — це не випадковість. Це результат накопленого memory pressure, який iOS та Android тихо копять, поки не убивають процес. SIGKILL приходить без логу, без стеку, без пояснень. Розробники часто списують це на «нестабільність руху», хоча реальна причина — неуправління ростом heap в Mono/IL2CPP та несвоєчасна виконання ассетів.

Проблема в тому, що Unity Memory Profiler часто показує «все нормально» — 400 МБ, видається, некритично. Але native-пам'ять, яку утримують об'єкти Texture2D без явних посилань, там не видна. Потрібен Total System Memory з Profiler window, а не тільки Managed Heap.

Три джерела витоків, які ми знаходимо в кожному другому проекті

Незакриті AssetBundle-посилання. Розробник завантажив AssetBundle, витяг з нього спрайт, але не викликав bundle.Unload(false). Спрайт в пам'яті. Потім спрайт знищений, але нативний об'єкт Texture2D все ще утримується через WeakReference в ResourceManager. Після 10 завантажень/виконання локацій — пам'ять не повертається. Класична фрагментація Unity native heap. Рішення: перехід на Addressables з явним управлінням часом життя через AsyncOperationHandle.Release().

Дублювання текстур при зміні сцен. При переході між сценами через SceneManager.LoadScene з параметром LoadSceneMode.Single стара сцена виконується, але якщо в новій сценці є текстури з тими ж іменами, завантажені через Resources.Load в коді — вони можуть опинитися в пам'яті двічі до виклику Resources.UnloadUnusedAssets(). На проектах з важкими сценами (100+ МБ текстур) це призводить до піку споживання пам'яті в момент переходу — саме тоді відбуваються крахи.

AudioClip з неправильними настройками Load Type. AudioClip з Load Type = Decompress On Load розпаковує PCM в пам'ять при завантаженні та тримає там. Для довгої музичної теми це може бути 50–80 МБ тільки для одного клипу. Правило: музика → Streaming, короткі SFX → Compressed In Memory, критичні SFX з мінімальною затримкою → Decompress On Load тільки якщо довжина < 2 секунд.

Як ми працюємо з пам'яттю

Memory Profiler (com.unity.memoryprofiler) — основний інструмент. Робимо снимок в кількох точках ігрового сеансу: після старту, після завантаження першої сцени, в середині геймплею, після зміни сцени. Порівнюємо через Compare Snapshots. Шукаємо об'єкти, які зростають від снимка до снимка і не повинні.

Особливо важливо звернути увагу на Texture2D в списку Objects. Сортуємо по Memory Size, відкриваємо References для підозрілих об'єктів — дивимось, хто їх утримує.

Addressables як архітектурне рішення. Перехід з Resources на Addressables дає явний контроль над часом життя ассетів. AssetReference + LoadAssetAsync + Release — повний цикл без «магії». Настроюємо профілі пам'яті через Addressables Analyze: Check Duplicate Bundle Dependencies знаходить ассети, упаковані в кілька бандлів одночасно (типова причина дублювання в пам'яті).

З практики: мобільний екшен, 9 рівнів. Після прохождення 3 рівнів підряд — крах на iPhone 8. Memory Profiler показав 847 МБ при старті 4 рівня. Джерело — 12 унікальних UI-атласів, завантажених через Resources.Load в Lobby-сценці, не виконані між рівнями. Після переносу на Addressables з явним Release при входженні в ігрову сцену та Resources.UnloadUnusedAssets в coroutine — пік знизився до 480 МБ.

Пул об'єктів замість Instantiate/Destroy. Кожен Instantiate виділяє нову пам'ять, кожен Destroy не повертає її миттєво — GC Alloc накопичується. Object Pool через Unity ObjectPool<T> (вбудована з 2021 LTS) повністю усуває цю категорію аллокацій для снарядів, ворогів, VFX.

Етапи роботи

  1. Зняття baseline-метрик через Profiler на цільовому пристрої (не Editor)
  2. Серія Memory Profiler snapshots по ігровому циклу
  3. Аналіз топ-10 об'єктів за споживанням пам'яті
  4. Виявлення джерел витоків через Compare Snapshots
  5. Пріоритизація по impact: текстури → AudioClip → Managed Heap → пулинг
  6. Реалізація виправлень з проміжними замірами
  7. Нагрузкове тестування: 1 година ігрової сесії без рестарту
Масштаб задачі Орієнтовні терміни
Аудит пам'яті + звіт 2–4 дні
Усунення 2–3 конкретних джерел витоків 1–2 тижні
Перехід Resources → Addressables + оптимізація 3–6 тижнів
Повна архітектурна переробка управління ассетами 6–12 тижнів

Вартість — після аудиту поточного стану проекту.