Is unnecessary mesh loading causing my performance spikes and how do I fix it?

So I am having an issue with there being a huge and visible performance spike about once per second; where a single frame seems to last 2-3 times longer than the others and it’s easy to notice. The profiler reveals the problem, but I’m unsure what is cause:

  • As you can see at the top there are two sets of green (rendering) spikes; smaller and more common spikes and less common but larger spikes.
  • In the memory row you can see that there an increase in mesh memory (orange) - right as the smaller set of spikes occurs, and that the mesh memory doesn’t stay in memory for very long.
  • Meanwhile the larger green spikes match up with garbage collection (gc allocated - the purple line in the memory column).
  • All spikes are being taken up by Gfx.WaitForPresent; which is really just a way for the system to wait until critically important things to finish before the CPU/GPU can continue and work on the next frame.

So it seems that the cause of the problem is that for some reason some mesh memory is being allocated more than once per second and then garbage collection has to clean it up, causing the huge spikes. But why?

I am 99% sure that nothing is being allocated by my scripts during run time. I am sure to never use the ‘new’ keyword (except for simple structs like Vector3) or Instantiate(…) in run time methods, instead I put my objects that appear & disappear during run time into object pools and have them all allocated at the start with Awake. And I definitely don’t have new models loaded during runtime. The memory row doesn’t state where the increase in mesh memory comes from unfortunately. My game doesn’t even use rig animations; in fact all meshes are unchanging atm. Is it some setting in my mesh imports? I am using .blend files in my project. When the little spikes happen it says that there are about 65 more objects in the scene. Also why does the mesh memory allocation decrease before the ‘GC Allocated’ spikes is that is when garbage collection happens?

But I am still unsure what could be causing this issue, and thought I would ask here to see if anyone more experienced than me has any ideas. While it really seems that the spikes line up with memory allocation and garbage collection could I be wrong with that being the issue?

That certainly looks like something in the rendering pipeline (not GC, not allocation, etc).

You should dig into what’s being rendered in that frame (look at the details - which we can’t see). What is the drawcall count? Could also be fillrate, are you drawing a bunch of large textures?

Looks like you are right, because I ran the game again while having the player do nothing except stare at the skybox and these spikes occurred again however this time they did not match up with when the gc allocation spikes (in fact the gc allocation spikes did not happen this time :eyes:). Just curious, how did you get a hunch that it is something in the rendering pipeline just by looking at my image?

The drawcalls remain at 16 even during the spikes.

I don’t know how to check the fillrate, I have no textures bigger than 2048x2048.

Perhaps it would help if I mentioned that I have a nice gaming computer and that every game I currently own I play at the highest graphics settings, so I think something weird is going on.

I remove everything in my scene, put the player on a large white cube with nothing else in the scene, and the spikes still happened.

Just a hunch based on experience :).

Gfx.WaitForPresent I believe means that it is waiting for the GPU to finish - hence it’s not in CPU land (so not GC or Scripts) which really only leaves the rendering pipeline.

If you’re drawing a lot of geometry (even with only 16 draw calls) you could hit fill rate issues. Is this profiling on a mobile build or are you looking in the editor?

If it’s the editor - try a standalone build - it could be the editor itself causing issues (even in standalone, you can get oddities like this just from profiling).

Dig into the details in the lower part of the profile window to see where the time is being spent there (batching??)