0
\$\begingroup\$

I have an issue where my game suddenly stops for a second and then continues. And I think it has something to do with my performance so I took at look at the profiler:

I tried to take a screenshot as soon as the crack happened:

enter image description here

enter image description here

However, since I am a bit new to optimization could anyone give me a helping hand on what might be the problem here?

\$\endgroup\$
1
  • \$\begingroup\$ From a first glance you can see that the crack happens excactly as the GC ( Garbage Collector ) does it's magic. Optimization in general is a thing that is hardly doable here since it requires to look at the complete code and investigate allocation of memory/object-references and if they are stuck or not freed soon enough etc. But as a hint I would say look if you can free some resources earlier or if some are kept initiated even without them needing to be initiated. \$\endgroup\$
    – Nico
    Oct 27, 2017 at 9:47

1 Answer 1

3
\$\begingroup\$

As Nico says, your profiler seems to show a big spike of garbage collector activity, which is consistent with the symptom of a sudden isolated stall.

This happens when your scripts allocate and then discard heap memory frequently. When a heap allocation request comes in and there's no longer enough untouched space left on the game's heap to fulfill it, the .Net/Mono runtime puts everything on hold while the garbage collector checks which previous allocations are no longer being used and clears them out, compacting the used portion heap to leave a nice big open space again. In a large & complicated game, a full sweep can take a significant amount of time.

To avoid this, take a look into which scripts are allocating lots of heap memory managed by the garbage collector — that's the GC Alloc column in the profiler, where I notice one line there allocated 2.0 MB in this frame. If that's happening frequently then it will definitely add up.

2.0 MB could be two 512 x 512 uncompressed RGBA textures, for instance. If you're allocating big blocks of memory like this, see if there are ways you can re-use them like a circular buffer or object pool, rather than continually allocating new ones. If you need temporary RenderTextures in particular, Unity has a built-in pool you can tap into with RenderTexture.Get/ReleaseTemporary.

Also watch for cases where two different scripts make a modified copy of a source asset each, even if the modification they needed was the same — you can cache and re-serve the existing copy instead of re-doing the work on a new one.

Creating new instances of reference types like Arrays/Lists, instantiating GameObjects, attaching Components, or modifying strings without a pre-allocated StringBuilder all create heap allocations too, though typically on a much smaller scale than textures, and more easily reclaimed.

If you're using Unity methods that return new arrays, like RaycastAll, check to see if they have a NonAlloc variant that lets you pass in your own buffer to populate, letting you re-use the same memory between calls.

For more information about reducing problems from garbage collection, see this Unity tutorial which goes into a lot of detail. :)

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .