One way to avoid unnecessary allocations on the managed heap is to adopt coding patterns that allow you to reuse parts of your memory allocations. The following examples outline approaches that can help improve the performance of your application.
There are a lot of cases where you can reduce the number of times that your application creates and destroys objects, to avoid generating garbage. There are certain types of objects in games, such as projectiles, which might appear over and over again even though only a small number are ever in play at once. In cases like this, you can reuse the objects, rather than destroy old ones and replace them with new ones.
For example, it’s not optimal to instantiate a new projectile object from a prefabAn asset type that allows you to store a GameObject complete with components and properties. The prefab acts as a template from which you can create new object instances in the scene. More info
See in Glossary every time one is fired. Instead, you can calculate the maximum number of projectiles that might ever exist simultaneously during gameplay, and instantiate an array of objects of the correct size when the game first enters the gameplay sceneA Scene contains the environments and menus of your game. Think of each unique Scene file as a unique level. In each Scene, you place your environments, obstacles, and decorations, essentially designing and building your game in pieces. More info
See in Glossary. To do this:
The ObjectPool
class provides an implementation of this reusable object pool technique, which is the easiest way to implement an object pool in your application.
However, if you’re using a version of Unity that doesn’t contain the ObjectPool
API, or you’d like to understand how you can implement a custom object pool, the following code shows a simple implementation of a stack-based object pool:
using System.Collections.Generic;
using UnityEngine;
public class ExampleObjectPool : MonoBehaviour {
public GameObject PrefabToPool;
public int MaxPoolSize = 10;
private Stack<GameObject> inactiveObjects = new Stack<GameObject>();
void Start() {
if (PrefabToPool != null) {
for (int i = 0; i < MaxPoolSize; ++i) {
var newObj = Instantiate(PrefabToPool);
newObj.SetActive(false);
inactiveObjects.Push(newObj);
}
}
}
public GameObject GetObjectFromPool() {
while (inactiveObjects.Count > 0) {
var obj = inactiveObjects.Pop();
if (obj != null) {
obj.SetActive(true);
return obj;
}
else {
Debug.LogWarning("Found a null object in the pool. Has some code outside the pool destroyed it?");
}
}
Debug.LogError("All pooled objects are already in use or have been destroyed");
return null;
}
public void ReturnObjectToPool(GameObject objectToDeactivate) {
if (objectToDeactivate != null) {
objectToDeactivate.SetActive(false);
inactiveObjects.Push(objectToDeactivate);
}
}
}
When you use arrays or classes from the System.Collection
namespace (for example, Lists or Dictionaries), it’s efficient to reuse or pool the allocated collection or array. Collection classes expose a Clear
method, which removes a collection’s values but doesn’t release the memory allocated to the collection.
This is useful if you want to allocate temporary helper collections for complex computations. The following code example demonstrates this:
// Bad C# script example. This Update method allocates a new `List` every frame.
void Update() {
List<float> nearestNeighbors = new List<float>();
findDistancesToNearestNeighbors(nearestNeighbors);
nearestNeighbors.Sort();
// … use the sorted list somehow …
}
This example code allocates the nearestNeighbors
List
once per frame to collect a set of data points.
You can hoist this List
out of the method and into the containing class, so that your code doesn’t need to allocate a new List
each frame:
// Good C# script example. This method re-uses the same List every frame.
List<float> m_NearestNeighbors = new List<float>();
void Update() {
m_NearestNeighbors.Clear();
findDistancesToNearestNeighbors(NearestNeighbors);
m_NearestNeighbors.Sort();
// … use the sorted list somehow …
}
This example code retains and reuses the List
instances memory across multiple frames. The code only allocates new memory when the List
needs to expand.
Did you find this page useful? Please give it a rating:
Thanks for rating this page!
What kind of problem would you like to report?
Thanks for letting us know! This page has been marked for review based on your feedback.
If you have time, you can provide more information to help us fix the problem faster.
Provide more information
You've told us this page needs code samples. If you'd like to help us further, you could provide a code sample, or tell us about what kind of code sample you'd like to see:
You've told us there are code samples on this page which don't work. If you know how to fix it, or have something better we could use instead, please let us know:
You've told us there is information missing from this page. Please tell us more about what's missing:
You've told us there is incorrect information on this page. If you know what we should change to make it correct, please tell us:
You've told us this page has unclear or confusing information. Please tell us more about what you found unclear or confusing, or let us know how we could make it clearer:
You've told us there is a spelling or grammar error on this page. Please tell us what's wrong:
You've told us this page has a problem. Please tell us more about what's wrong:
Thank you for helping to make the Unity documentation better!
Your feedback has been submitted as a ticket for our documentation team to review.
We are not able to reply to every ticket submitted.