Garbage detector from my Gamefest Slides

One of the last things in my slides for Gamefest was a simple little object I had written to help us detect when our code was allocating memory we weren’t expecting. Due to the size limitations of slides I had attempted to to shorten the object to the minimalist version, and in doing so lost a few things. Here is the object I used in its entirety:

Not very much different than what’s in the slides, but a few subtle differences. The most important being whether or not ‘true’ or “false” is passed in during the two calls to GetTotalMemory. What does this code actually do though?

I wrote it basically to allow myself to “wrap” a section of code and measure any allocations from it. At the constructor of the helper object I measure the total memory in use and store how much allocation (in bytes) I expect the code block to take. Then at the end I measure the memory once more and if more memory was allocated than I was expecting I break into the debugger.

A few things to note. First, when you pass in ‘true’ to GetTotalMemory a full collection will occur, so if you are doing this often you will dramatically¬†slow down your application.

Second, you’ll notice that the slides pass in ‘true’ in both spots which is probably not the behavior you want (you’ll notice in the code above that ‘false’ is passed at the end in the second constructor).¬†If you pass in true in both spots, you will only catch allocations that were not garbage because any garbage would have been collected due to the ‘true’ being passed in!

Now, there are times when you do want to know this, so having the option is certainly fine, but the majority of time you want to know about allocations that create garbage, in which case you need to pass in false to the second call.

Another point I brought up during the talk that isn’t obvious is that this code completely ignores other threads. Which means if you have another thread allocating memory in between the two calls, you will get “false positives” that can prove difficult to track down. When I used this method I kept the code I wrapped in this object small to help eliminate them.

To see an example of using this helper in code see below:

  1. Nice technique!

    This could miss allocations if the code being measured happened to allocate so much that it triggered a GC, though. It allocates, GC happens, then a tiny amount more allocation happens, then the Dispose method runs and sees used memory has only gone up a little, so fails to notice there is a problem.

    You could fix that by having the constructor also instantiate a new WeakReference(new object()). If that weak reference is invalid when Dispose runs, you know a GC took place in the interim, so should break even if memory usage does not appear to have gone up.

Leave a Comment

NOTE - You can use these HTML tags and attributes:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>