In the game I am currently working on, I was under the belief that I had no (or very few) memory allocations at run time. And this was true for the most part. The memory allocations that were still occurring were either from the .NET Framework or XNA on the PC (I’m looking at you, MouseMove messages) or allocations that we couldn’t track because they only happened on the phone and there is no equivalent to CLR Profiler on the phone yet. What I didn’t count on was that many of the entities in a level were not being destroyed at the end of a level.
During all of my memory testing, I had loaded into a level once, tested, then exited the game. Not once had I loaded into a level, then loaded into another level or even the same level a second time. If I had, I would have noticed that large chunks of memory were being left behind but unable to be garbage collected. Once this was brought to my attention, it was trivial to see the symptoms in CLR Profiler (the ever-climbing bar graph in the timeline was a dead give-away), and it could tell me what objects they were (animation keyframes, bones, etc), but the most important piece of information was one that CLR Profiler could not easily tell me: Who was holding the reference to these objects that was preventing them from being garbage collected?
I had spent two days working with a Windows version of my Windows Phone game in CLR Profiler trying to find these retained references, and had still not got any closer. Then it was suggested on the Twitter-verse that I try ANTS Memory Profiler from Red Gate. It has a 14-day evaluation period, but I did not need anywhere near this length of time. I installed the evaluation version, ran the game, checked the results, found the objects left behind and I could easily see who was retaining references to these objects. A total time of just under fifteen minutes. The culprit was a global dictionary used as a pool for infantry units, and I had simply omitted the single line of code to clear the pool when unloading the level.
What had taken me at least two days in CLR Profiler (and still hadn’t got a result) I achieved in fifteen minutes with ANTS Memory Profiler. That just shows that you can be a lot more productive if you use the right tools for the job. This may sound like an advertisement or one of those cheesy infomercials. It’s not intended to be. I’m just a) frustrated I had spent so long getting nowhere, and b) happy to to find the cause of the problem. CLR Profiler is a great tool, and it’s free, and has solved many run-time memory allocation issues we had. In this case though, it could not tell me the information I required. Red Gate’s profiler was the right tool for this job.
Update: There are now some powerful profiling tools that work on the device, and you already have them.