Memory References for Dynamically Instantiated Prefabs

I have a question about memory managment & Instantiating Prefabs.

Lets imagine I have a Parent Object called AllCars that is in charge of spawning vehicles like cars etc. The user can change the cars on the fly so the Parent Object (All Cars) has a reference to all the possible car Prefabs stored in an array and the current index of which car is selected.

When selecting a new car the code will:

//Destory Old Car Object
Destroy(currentCar);

//Create a New Car Object
var currentCar = Instantiate(Cars[carIndex], this.transform);

My question is about memory reference. When I look at the Profiler not only is the currentCar (mesh texture etc) referenced in memory but all the possible Cars that can be instantiated by the Parent Object are loaded into memory.

I would expect that only the Instantiated currentCar object would be loaded into memory and then it would be released once currentCar is Destoryed.

I have done some initial reading on Asset Bundles and Resource.Load as a way to maybe address this. But I am not sure which way to go. Or maybe there is a different, better (easier) way.

Thank you

You haven’t specified how or if you’re explicitly “loading the cars.” Assuming you’re using Resources.Load(asset[i]), then it will load all cars into memory:

Loads the asset of the requested type stored at path in a Resources folder.

This method returns the asset at path if it can be found, otherwise it returns null.
Unity - Scripting API: Resources.Load

Keep in mind:

  • Resources.Load() only loads the asset; it does not instantiate it.
  • Assets loaded with Resources.Load() remain in memory until manually unloaded using Resources.UnloadAsset() or Resources.UnloadUnusedAssets().
  • For better performance and memory management, check out Addressables instead of Resources.Load() Unity - Manual: Addressables
1 Like

Currently I am not using Resource.Load() I am just Instatiating a Prefab that I reference in allCars. I asked the same question to Deepseek/ChatGTP and they suggested Addressables as well.

Oh, the way your question was worded it confused me when you brought up .Load().

So going to assume again that you’re just adding your “prefabs” to a collection on your AllCars. If that’s the case there’s a reference to the prefab so it will be loaded into memory ready to be instanced. Anything referenced in a scene is loaded in memory.

.Destroy() only destroys the created instance of the prefab, to go a little further, Prefabs are templates that can be used to create new objects in a scene. When you Instance them then they are objects.

If you use Addressable you can choose what you load and also .Release() any assets you don’t want loaded in memory.

Unity is loading anything referenced by the scene into RAM.
In theory you can take non-instantiated prefab in code, get its components, textures, meshes etc., because it’s already in memory and everything will have a valid value.
If you want to actually load things from disk to RAM and unload them later you will need Addressables.

The simplest solution is to use Resources:

private Car CreateCar(int carIndex)
{
	string resourcePath = carResourcePaths[carIndex];
	Car prefab = Resources.Load<Car>(resourcePath);
	Car instance = Instantiate(prefab, transform);
	prefab = null;
	Resources.UnloadUnusedAssets();
	return instance;
}

If you need more control than this, use Addressables.

You usually don’t want to work with AssetBundles directly; it’s more of a lower level API, which things like Addressables use internally.

1 Like