In this lesson, you will learn how to stabilize your frame rate by replacing heap-allocated objects with efficient object pools and stack-allocated structs.
When you use new to instantiate game objects or classes, memory is allocated on the managed heap. Eventually, the Garbage Collector (GC) must traverse this heap to reclaim unused memory; if the GC takes too long, your game will suffer from a noticeable frame-stutter. To prevent this, we must minimize "garbage" generation during gameplay.
Implementing Object Pooling
Instead of destroying and instantiating projectiles or enemies—which creates constant heap garbage—we use Object Pooling. By pre-instantiating a fixed set of objects and toggling their SetActive state, we keep memory usage flat.
// Instead of Instantiate(projectile)
// Use a pre-warmed list:
public class ProjectilePool : MonoBehaviour {
private Queue<GameObject> pool = new Queue<GameObject>();
public GameObject Get() {
GameObject obj = pool.Dequeue();
obj.SetActive(true);
return obj;
}
}
Leveraging Structs for Data
Classes are reference types stored on the heap, while structs are value types stored on the stack. If you have a system processing thousands of data points—like a particle simulation or pathfinding nodes—switching from a class to a struct avoids heap allocation entirely.
// Structs are stored on the stack, not the heap
public struct ParticleData {
public Vector3 position;
public Vector3 velocity;
public float lifeTime;
}
// Processing this array causes zero GC pressure
ParticleData[] particles = new ParticleData[1000];
By using structs for small, temporary data containers, you keep your memory layout compact and CPU-friendly. When you combine this with an object pool to recycle your heavy MonoBehaviour instances, the GC has significantly less work to do. This ensures that your game logic spends its cycles on gameplay, not on cleaning up after short-lived allocations.
Key Takeaway: To eliminate frame-stutter, recycle existing objects via pools and favor stack-allocated structs over heap-allocated classes for frequently accessed data.