Memory leak: Terrain Data stays in memory after being unloaded

Hi,

We’re using a streaming system that loads and unloads scenes around our player. One of the scene collections are scenes containing terrains.

We noticed that when we drive around in our world, terrainData from terrains that get unloaded will stay in memory unless we call UnloadUnusedAssets(); which would cause lag spikes. We prefer having garbage collection do its job. We also have incremental GC enabled.

Now, how can I make sure the terrainData gets released from memory when having no references anymore? Is this a bug from our Unity version?

FWIW we are on 2021.3.33f1.

Our game is already released and we really need to fix that ASAP. I’ve tried manually destroying (DestroyImmediate) the terraindata when unloading the scene, but then if you need to load it back, the terrainData doesn’t exist anymore.

Thanks so much.

The manual states:

Note: Assets are currently not unloaded. In order to free up asset memory call Resources.UnloadUnusedAssets.

Unloading does take a hit for certain. There is no way around that. Check with the profiler what exactly causes the most drain on the CPU. Perhaps it’s not even the asset unloading but some other aspect.

Also try to profile terrain scenes with little to no content vs lots of content. You may find that some content is more “heavy” and if so, it becomes a matter of identifying and optimizing those parts of the terrain. Or cutting the terrain into either smaller or bigger chunks.

@CodeSmile Thanks for your answer. I would love to be able to unload the terrain data specifically because as stated, Resources.UnloadUnusedAssets makes the game freeze for half a second every time it’s called. and if I don’t call it and just let the engine do garbage collection, the game runs fine (except for the memory issue with terrainData). We’ve been analyzing our memory and it’s really the terrainData’s splatmap textures that are staying in memory and are causing our issues. That’s the only thing we need to get rid of.

Garbage Collection deals with Managed Memory and has nothing to do with Native Memory unloading. That’s why Resources.UnloadUnusedAssets is sometimes also dubbed the Asset GC.

You might want to put your terrain data into Asset Bundles or Addressable a if you want more explicit control about unloading it.

Also DestroyImmediate is for in-Editor usage to remove Assets there, and not meant for runtime usage. Try again with Destroy, maybe that suffices

Sweet, thank you. I’ve changed my entire streaming setup to use Addressables now.

Quick question in order to optimize our build times.

Since the streamed scenes are now addressables, Unity unchecked them for me in the build settings. That makes sense to me.

However, does the build process still need to build the scenes like when they were not addressables, or should it only go through the addressable packaging process?

I’m asking because I started a build, with my thousands of addressables scenes unchecked in build settings, and it still seems to be building scenes. This can make sense that it still has to build the scenes, I just wanted to make sure if I had, for example, to completely remove the scenes from the build settings to clear that step:

Opening scene 'Assets/WorldStreamer/SplitScenes/outbrkSmallerTerrain/outbrkSmallerTerrain_x-6_z19.unity'
Unloading 64 Unused Serialized files (Serialized files now loaded: 0)
Loaded scene 'Assets/WorldStreamer/SplitScenes/outbrkSmallerTerrain/outbrkSmallerTerrain_x-6_z19.unity'
	Deserialize:            8.492 ms
	Integration:            496.767 ms
	Integration of assets:  0.002 ms
	Thread Wait Time:       0.009 ms
	Total Operation Time:   505.270 ms
Unloading 106 unused Assets / (379.1 KB). Loaded Objects now: 30806.
Memory consumption went from 2.84 GB to 2.84 GB.
Total: 56.820000 ms (FindLiveObjects: 2.122600 ms CreateObjectMapping: 2.330300 ms MarkObjects: 51.536400 ms  DeleteObjects: 0.829400 ms)

Unloading 88 Unused Serialized files (Serialized files now loaded: 0)

Edit: I have tried completely removing them from the list, build is still working on every scene one by one just like when it was included as normal scenes in the build settings.

Too bad, I had hoped for a faster build process :stuck_out_tongue: When you have thousands of scenes because you have a huge world, your build time bottleneck is this step, which seems inevitable.