Unity3D Profiler gives me spikes that is mostly about garbage collection. In the screenshot below, the three red spikes represent three stalls that I had in my gameplay. Each of these stalls are 100+ms and most of the time was spent on TrackDependencies
.
According to Unity instruction, I tried adding this to my code:
if (Time.frameCount % 30 == 0)
{
System.GC.Collect();
}
This didn't help. I still have spikes and they still take 100+ms. What exactly is going on and what can I do to optimize my game?
PS:
I am dynamically creating and destroying a lot of GameObject
s in my game. Could that be a problem?
I don't have string concatenation in a loop or array as return value as caveated in the post.
This didn't help. I still have spikes and they still take 100+ms. What
exactly is going on and what can I do to optimize my game?
With System.GC.Collect
you are simply force a garbage collection. If you have allocated a lot of memory to be deallocated from the last collect, than you can't avoid spikes. This is only useful in order to try to distribute garbage collection over time avoiding a massive deallocation.
I am dynamically creating and destroying a lot of GameObjects in my
game. Could that be a problem?
Probably this could be the problem.
Some hints:
- Try to allocate (
LoadResource
and Instantiate
) as much as possible of your resources at the begin of you application. If the memory required isn't too much, you can simply instantiate all the resources you need and disable/enable them on demand. If the resource memory requirements are huge this is not achievable.
- Avoid ingame calls to
Instantiate
and Destroy
. Create a pool of object where a set of resources is Instantiated when the application starts. Enable the resources you need, and disable all the rest. Instead of destroying an object release it to the pool, so that it can be disabled and reanabled on demand.
- Avoid ingame calls to
Resources.UnloadUnusedAssets
. This can only increase the time required to Instantiate a new resource if you have previously release it. It is useful to opitmize memory usage, but calling it at costant intervals or every time you destroy an object makes no sense.