Marketplace

memory-management

Game memory optimization, object pooling, garbage collection tuning, and efficient resource management for target platforms.

$ Installer

git clone https://github.com/pluginagentmarketplace/custom-plugin-game-developer /tmp/custom-plugin-game-developer && cp -r /tmp/custom-plugin-game-developer/skills/memory-management ~/.claude/skills/custom-plugin-game-developer

// tip: Run this command in your terminal to install the skill


name: memory-management version: "2.0.0" description: | Game memory optimization, object pooling, garbage collection tuning, and efficient resource management for target platforms. sasmp_version: "1.3.0" bonded_agent: 02-game-programmer bond_type: PRIMARY_BOND

parameters:

  • name: platform type: string required: false validation: enum: [pc, console, mobile, vr, web]
  • name: issue_type type: string required: false validation: enum: [leak, fragmentation, gc_spikes, budget_exceeded]

retry_policy: enabled: true max_attempts: 3 backoff: exponential

observability: log_events: [start, complete, error, gc_collect] metrics: [heap_size_mb, gc_time_ms, allocation_rate, pool_usage]

Memory Management

Memory Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    GAME MEMORY LAYOUT                        β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  STACK (Fast, Auto-managed):                                 β”‚
β”‚  β”œβ”€ Local variables                                         β”‚
β”‚  β”œβ”€ Function parameters                                     β”‚
β”‚  └─ Return addresses                                        β”‚
β”‚                                                              β”‚
β”‚  HEAP (Slower, Manual/GC-managed):                           β”‚
β”‚  β”œβ”€ Dynamic allocations (new/malloc)                        β”‚
β”‚  β”œβ”€ Game objects                                            β”‚
β”‚  └─ Asset data                                              β”‚
β”‚                                                              β”‚
β”‚  STATIC (Fixed at compile time):                             β”‚
β”‚  β”œβ”€ Global variables                                        β”‚
β”‚  β”œβ”€ Static class members                                    β”‚
β”‚  └─ Constant data                                           β”‚
β”‚                                                              β”‚
β”‚  VRAM (GPU Memory):                                          β”‚
β”‚  β”œβ”€ Textures                                                β”‚
β”‚  β”œβ”€ Meshes                                                  β”‚
β”‚  └─ Render targets                                          β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Platform Memory Budgets

MEMORY BUDGET GUIDELINES:
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  PLATFORM      β”‚ TOTAL    β”‚ GAME LOGIC β”‚ ASSETS   β”‚ BUFFER β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  Mobile Low    β”‚ 512 MB   β”‚ 50 MB      β”‚ 350 MB   β”‚ 112 MB β”‚
β”‚  Mobile High   β”‚ 2 GB     β”‚ 200 MB     β”‚ 1.5 GB   β”‚ 300 MB β”‚
β”‚  Console       β”‚ 8 GB     β”‚ 500 MB     β”‚ 6 GB     β”‚ 1.5 GB β”‚
β”‚  PC Min        β”‚ 4 GB     β”‚ 300 MB     β”‚ 3 GB     β”‚ 700 MB β”‚
β”‚  PC High       β”‚ 16 GB    β”‚ 1 GB       β”‚ 12 GB    β”‚ 3 GB   β”‚
β”‚  VR            β”‚ 8 GB     β”‚ 400 MB     β”‚ 6 GB     β”‚ 1.6 GB β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”˜

VRAM BUDGETS:
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Mobile:    512 MB - 1 GB                                   β”‚
β”‚  Console:   8-12 GB (shared with RAM)                       β”‚
β”‚  PC Low:    2-4 GB                                          β”‚
β”‚  PC High:   8-16 GB                                         β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Object Pooling

// βœ… Production-Ready: Generic Object Pool
public class ObjectPool<T> where T : class
{
    private readonly Stack<T> _pool;
    private readonly Func<T> _createFunc;
    private readonly Action<T> _onGet;
    private readonly Action<T> _onReturn;
    private readonly int _maxSize;

    public int CountActive { get; private set; }
    public int CountInPool => _pool.Count;

    public ObjectPool(
        Func<T> createFunc,
        Action<T> onGet = null,
        Action<T> onReturn = null,
        int initialSize = 10,
        int maxSize = 100)
    {
        _createFunc = createFunc;
        _onGet = onGet;
        _onReturn = onReturn;
        _maxSize = maxSize;
        _pool = new Stack<T>(initialSize);

        // Pre-warm pool
        for (int i = 0; i < initialSize; i++)
        {
            _pool.Push(_createFunc());
        }
    }

    public T Get()
    {
        T item = _pool.Count > 0 ? _pool.Pop() : _createFunc();
        _onGet?.Invoke(item);
        CountActive++;
        return item;
    }

    public void Return(T item)
    {
        if (item == null) return;

        _onReturn?.Invoke(item);
        CountActive--;

        if (_pool.Count < _maxSize)
        {
            _pool.Push(item);
        }
        // If pool is full, let GC collect the item
    }

    public void Clear()
    {
        _pool.Clear();
        CountActive = 0;
    }
}

// Usage Example: Bullet Pool
public class BulletManager : MonoBehaviour
{
    private ObjectPool<Bullet> _bulletPool;

    void Awake()
    {
        _bulletPool = new ObjectPool<Bullet>(
            createFunc: () => Instantiate(bulletPrefab).GetComponent<Bullet>(),
            onGet: bullet => bullet.gameObject.SetActive(true),
            onReturn: bullet => bullet.gameObject.SetActive(false),
            initialSize: 50,
            maxSize: 200
        );
    }

    public Bullet SpawnBullet(Vector3 position, Vector3 direction)
    {
        var bullet = _bulletPool.Get();
        bullet.Initialize(position, direction);
        bullet.OnDestroyed += () => _bulletPool.Return(bullet);
        return bullet;
    }
}

Garbage Collection Optimization

GC SPIKE PREVENTION:
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  AVOID IN UPDATE/HOT PATHS:                                  β”‚
β”‚  βœ— new object()                                             β”‚
β”‚  βœ— string concatenation ("a" + "b")                         β”‚
β”‚  βœ— LINQ queries (ToList(), Where(), etc.)                   β”‚
β”‚  βœ— Boxing value types                                       β”‚
β”‚  βœ— Closures/lambdas capturing variables                     β”‚
β”‚  βœ— foreach on non-struct enumerators                        β”‚
β”‚                                                              β”‚
β”‚  DO INSTEAD:                                                 β”‚
β”‚  βœ“ Object pooling                                           β”‚
β”‚  βœ“ StringBuilder for strings                                β”‚
β”‚  βœ“ Pre-allocated collections                                β”‚
β”‚  βœ“ Struct-based data                                        β”‚
β”‚  βœ“ Cache delegates                                          β”‚
β”‚  βœ“ for loops with index                                     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
// βœ… Production-Ready: Allocation-Free Patterns
public class AllocationFreePatterns
{
    // ❌ BAD: Allocates every frame
    void BadUpdate()
    {
        string status = "Health: " + health + "/" + maxHealth; // Allocates
        var enemies = allEntities.Where(e => e.IsEnemy).ToList(); // Allocates
        foreach (var enemy in enemies) { } // May allocate enumerator
    }

    // βœ“ GOOD: Zero allocations
    private StringBuilder _sb = new StringBuilder(64);
    private List<Entity> _enemyCache = new List<Entity>(100);

    void GoodUpdate()
    {
        // Reuse StringBuilder
        _sb.Clear();
        _sb.Append("Health: ").Append(health).Append("/").Append(maxHealth);

        // Reuse list, avoid LINQ
        _enemyCache.Clear();
        for (int i = 0; i < allEntities.Count; i++)
        {
            if (allEntities[i].IsEnemy)
                _enemyCache.Add(allEntities[i]);
        }

        // Index-based iteration
        for (int i = 0; i < _enemyCache.Count; i++)
        {
            ProcessEnemy(_enemyCache[i]);
        }
    }
}

Memory Profiling

PROFILING WORKFLOW:
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  1. BASELINE: Measure memory at known state                 β”‚
β”‚     β†’ Startup, menu, gameplay, level transition            β”‚
β”‚                                                              β”‚
β”‚  2. MONITOR: Track over time                                β”‚
β”‚     β†’ Memory growth indicates leaks                         β”‚
β”‚     β†’ Spikes indicate heavy allocations                    β”‚
β”‚                                                              β”‚
β”‚  3. SNAPSHOT: Capture heap at suspicious moments            β”‚
β”‚     β†’ Compare snapshots to find what's growing             β”‚
β”‚                                                              β”‚
β”‚  4. TRACE: Find allocation source                           β”‚
β”‚     β†’ Stack trace shows where allocation happened          β”‚
β”‚     β†’ Identify hot paths                                   β”‚
β”‚                                                              β”‚
β”‚  5. FIX: Apply optimization                                 β”‚
β”‚     β†’ Pool, cache, or eliminate allocation                 β”‚
β”‚                                                              β”‚
β”‚  6. VERIFY: Confirm fix worked                              β”‚
β”‚     β†’ Re-profile same scenario                             β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

PROFILING TOOLS:
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Unity:                                                      β”‚
β”‚  β€’ Memory Profiler (Package)                                β”‚
β”‚  β€’ Profiler window (Memory section)                         β”‚
β”‚  β€’ Deep Profile mode                                        β”‚
β”‚                                                              β”‚
β”‚  Unreal:                                                     β”‚
β”‚  β€’ Unreal Insights                                          β”‚
β”‚  β€’ memreport command                                        β”‚
β”‚  β€’ stat memory                                              β”‚
β”‚                                                              β”‚
β”‚  Native:                                                     β”‚
β”‚  β€’ Valgrind (Linux)                                         β”‚
β”‚  β€’ Instruments (macOS)                                      β”‚
β”‚  β€’ Visual Studio Diagnostic Tools                           β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Asset Streaming

STREAMING STRATEGY:
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    STREAMING ZONES                           β”‚
β”‚                                                              β”‚
β”‚     [Loaded]  [Loading...]  [Unloaded]  [Unloaded]         β”‚
β”‚        β–²           β–²            β”‚            β”‚              β”‚
β”‚        β”‚           β”‚            β”‚            β”‚              β”‚
β”‚  ──────●───────────●────────────●────────────●──────        β”‚
β”‚     Player      Trigger     Far Zone     Very Far           β”‚
β”‚     Position                                                 β”‚
β”‚                                                              β”‚
β”‚  STREAMING RULES:                                            β”‚
β”‚  β€’ Load when player approaches (predictive)                 β”‚
β”‚  β€’ Unload when player far away + timeout                   β”‚
β”‚  β€’ Priority: Visible > Nearby > Background                 β”‚
β”‚  β€’ Async loading to avoid hitches                          β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
// βœ… Production-Ready: Asset Streaming Manager
public class StreamingManager : MonoBehaviour
{
    [SerializeField] private float loadDistance = 50f;
    [SerializeField] private float unloadDistance = 100f;
    [SerializeField] private float unloadDelay = 5f;

    private Dictionary<string, StreamingZone> _zones = new();
    private Queue<AsyncOperation> _loadQueue = new();

    void Update()
    {
        Vector3 playerPos = Player.Position;

        foreach (var zone in _zones.Values)
        {
            float distance = Vector3.Distance(playerPos, zone.Center);

            if (distance < loadDistance && !zone.IsLoaded)
            {
                StartCoroutine(LoadZoneAsync(zone));
            }
            else if (distance > unloadDistance && zone.IsLoaded)
            {
                StartCoroutine(UnloadZoneDelayed(zone, unloadDelay));
            }
        }
    }

    private IEnumerator LoadZoneAsync(StreamingZone zone)
    {
        zone.State = ZoneState.Loading;

        var operation = SceneManager.LoadSceneAsync(zone.SceneName, LoadSceneMode.Additive);
        operation.allowSceneActivation = false;

        while (operation.progress < 0.9f)
        {
            yield return null;
        }

        operation.allowSceneActivation = true;
        zone.State = ZoneState.Loaded;
    }
}

πŸ”§ Troubleshooting

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ PROBLEM: Memory keeps growing over time (leak)              β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ DEBUG:                                                       β”‚
β”‚ β†’ Take memory snapshots at intervals                        β”‚
β”‚ β†’ Compare snapshots to find growing objects                 β”‚
β”‚ β†’ Check for missing unsubscribes (events)                   β”‚
β”‚ β†’ Look for collections that never clear                     β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ SOLUTIONS:                                                   β”‚
β”‚ β†’ Implement IDisposable pattern                             β”‚
β”‚ β†’ Use weak references for caches                            β”‚
β”‚ β†’ Clear collections when changing scenes                    β”‚
β”‚ β†’ Unsubscribe from events in OnDestroy                      β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ PROBLEM: GC causing frame spikes                            β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ DEBUG:                                                       β”‚
β”‚ β†’ Profile with GC.Alloc markers                             β”‚
β”‚ β†’ Look for allocations in Update/FixedUpdate               β”‚
β”‚ β†’ Check for string operations in hot paths                  β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ SOLUTIONS:                                                   β”‚
β”‚ β†’ Implement object pooling                                  β”‚
β”‚ β†’ Use structs instead of classes where possible             β”‚
β”‚ β†’ Pre-allocate collections with known capacity              β”‚
β”‚ β†’ Spread GC across frames (incremental GC)                  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ PROBLEM: Out of memory on mobile                            β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ DEBUG:                                                       β”‚
β”‚ β†’ Check texture memory usage                                β”‚
β”‚ β†’ Look for duplicate assets                                 β”‚
β”‚ β†’ Monitor during level transitions                          β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ SOLUTIONS:                                                   β”‚
β”‚ β†’ Reduce texture resolution                                 β”‚
β”‚ β†’ Implement aggressive streaming                            β”‚
β”‚ β†’ Unload unused assets (Resources.UnloadUnusedAssets)       β”‚
β”‚ β†’ Use compressed texture formats                            β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ PROBLEM: Hitches during level loading                       β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ SOLUTIONS:                                                   β”‚
β”‚ β†’ Use async loading (LoadSceneAsync)                        β”‚
β”‚ β†’ Spread instantiation across frames                        β”‚
β”‚ β†’ Pre-warm object pools during loading screen               β”‚
β”‚ β†’ Stream assets instead of loading all at once              β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Memory Optimization Checklist

AreaTechniqueImpactEffort
ObjectsObject PoolingHighMedium
StringsStringBuilderMediumLow
CollectionsPre-allocationMediumLow
AssetsStreamingHighHigh
TexturesCompressionHighLow
GCIncremental GCMediumLow
EventsWeak ReferencesLowMedium

Use this skill: When optimizing memory usage, reducing frame stutters, or supporting mobile platforms.