Note on frame skips and jerkiness

I noticed regular jerkiness in the frame rate of even my simple test app so did some experiments. Hopefully this will help others and possibly the devs. For reference I am running:

  • MonoGame WindowsGL built from source (Commit 86673fd)
  • Visual Studio 2013
  • Windows 8

Both versions of my test app were drawing small numbers of simple primitives to the screen using BasicEffect. It should not have been anywhere near stressing my test machine. I added some logging and this is sample output given by the noticeably jerky version of the app:

Update
Render
Update
Garbage Collection
Render
Update
Update
Update
Update
Render
Update
Render

Notice that multiple rendering frames are skipped when GC hits. Investigating I found that the app was creating many instances of BasicEffect, 15 per rendering frame! Additionally the instances were not being disposed but left for GC to clean up. Either disposing the instances at the end of each frame, or even better caching them and holding them for the life of the application immediately removes any jerkiness and gives the following log:

Update
Render
Update
Garbage Collection Detected
Render
Update
Render
Update
Render

Note that every update is matched with a render and that the garbage collection does not have a noticeable impact.

Hopefully this will help others diagnose any frame skipping issues of their own.

Disposing an object will not remove it from GC. You have to avoid new allocations. Using a pool as you said to reuse objects is a good advice. Another way is to use structs instead of classes when possible & size of the object is small. Take care to pass those structs as ref to methods.

No it wont, but in this case it does make a visible performance difference disposing explicitly rather than (sloppily) leaving it up to the GC to time it. I haven’t looked in depth at why.

by calling Dispose() you reclaim unmanaged resources that GC doesn’t see. It shouldn’t make any difference on how often the GC is triggered. What is strange in the second case GC happens but doesn’t take much time to cause draw frames to drop.

My guess is that in the first case GC calls the finalizer/destructor on BasicEffect objects which in turn dispose any managed resources. Releasing thousand of resources in one go!

.

Short version: Dispose properly, and pool objects if you can, like all good .NET coders.