Game RAM Usage Optimization
Crash without warning on 3 GB RAM devices — it's not random. It's result of accumulated memory pressure that iOS and Android silently accumulate until they kill the process. SIGKILL comes without log, without stack, without explanation. Developers often blame it on "engine instability," but the real cause is uncontrolled heap growth in Mono/IL2CPP and untimely asset unloading.
Problem is Unity Memory Profiler often shows "all normal" — 400 MB seems non-critical. But native-memory held by Texture2D objects without explicit references is invisible. Need Total System Memory from Profiler window, not just Managed Heap.
Three leak sources we find in every second project
Unclosed AssetBundle references. Developer loaded AssetBundle, extracted sprite from it, but didn't call bundle.Unload(false). Sprite in memory. Then sprite destroyed, but native Texture2D object still held via WeakReference in ResourceManager. After 10 location load/unload cycles — memory not returned. Classic Unity native heap fragmentation. Solution: move to Addressables with explicit lifetime control via AsyncOperationHandle.Release().
Texture duplication on scene change. When switching scenes via SceneManager.LoadScene with LoadSceneMode.Single, old scene unloads, but if new scene has textures with same names loaded via Resources.Load in code — they can end up in memory twice until Resources.UnloadUnusedAssets() call. On projects with heavy scenes (100+ MB textures) this causes memory peak during transition — exactly when crashes happen.
AudioClip with wrong Load Type settings. AudioClip with Load Type = Decompress On Load decompresses PCM into memory on load and keeps it there. For long music theme this can be 50–80 MB for just one clip. Rule: music → Streaming, short SFX → Compressed In Memory, critical SFX with minimum latency → Decompress On Load only if length < 2 seconds.
How we work with memory
Memory Profiler (com.unity.memoryprofiler) — main tool. Take snapshot at several points of game session: after startup, after first scene load, mid-gameplay, after scene change. Compare via Compare Snapshots. Look for objects growing between snapshots that shouldn't.
Special attention to Texture2D in Objects list. Sort by Memory Size, open References for suspicious objects — see who holds them.
Addressables as architectural solution. Move from Resources to Addressables gives explicit lifetime control. AssetReference + LoadAssetAsync + Release — complete cycle without "magic." Configure memory profiles via Addressables Analyze: Check Duplicate Bundle Dependencies finds assets packed into multiple bundles simultaneously (typical duplication cause in memory).
From practice: mobile action, 9 levels. After completing 3 levels in a row — crash on iPhone 8. Memory Profiler showed 847 MB at level 4 start. Source — 12 unique UI atlases loaded via Resources.Load in Lobby scene, not unloaded between levels. After moving to Addressables with explicit Release on game scene entry and Resources.UnloadUnusedAssets in coroutine — peak dropped to 480 MB.
Object pools instead of Instantiate/Destroy. Each Instantiate allocates new memory, each Destroy doesn't return it immediately — GC Alloc accumulates. Object Pool via Unity ObjectPool<T> (built-in since 2021 LTS) completely eliminates this category of allocations for projectiles, enemies, VFX.
Work stages
- Baseline metric capture via Profiler on target device (not Editor)
- Series of Memory Profiler snapshots across game cycle
- Analysis of top-10 objects by memory consumption
- Identify leak sources via Compare Snapshots
- Prioritize by impact: textures → AudioClip → Managed Heap → pooling
- Implement fixes with intermediate measurements
- Stress test: 1 hour gameplay session without restart
| Task Scope | Estimated Timeline |
|---|---|
| Memory audit + report | 2–4 days |
| Fix 2–3 specific leak sources | 1–2 weeks |
| Resources → Addressables transition + optimization | 3–6 weeks |
| Full asset management architectural rework | 6–12 weeks |
Cost determined after audit of project's current state.





