Marketplace
memory-management
Game memory optimization, object pooling, garbage collection tuning, and efficient resource management for target platforms.
$ Instalar
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
SKILL.md
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
| Area | Technique | Impact | Effort |
|---|---|---|---|
| Objects | Object Pooling | High | Medium |
| Strings | StringBuilder | Medium | Low |
| Collections | Pre-allocation | Medium | Low |
| Assets | Streaming | High | High |
| Textures | Compression | High | Low |
| GC | Incremental GC | Medium | Low |
| Events | Weak References | Low | Medium |
Use this skill: When optimizing memory usage, reducing frame stutters, or supporting mobile platforms.
Repository

pluginagentmarketplace
Author
pluginagentmarketplace/custom-plugin-game-developer/skills/memory-management
1
Stars
0
Forks
Updated1d ago
Added1w ago