7

I have a C# XNA on WP7 project running and I'm finding that it's eating up memory between screen changes and not returning it, eventually leading to an outofmemoryexception.

I've looked and looked but I can't for the life of me find where this memory is going.

is there any way I can find out where the memory is being used and why it's not being given back to the device?

Thanks for any help!

meds
  • 21,699
  • 37
  • 163
  • 314

6 Answers6

6

Use Microsoft's CLR Profiler for .NET Framework 4 (free) on the Windows version of your project.

Using this you can get a timeline of your project's memory allocations. Or you can inspect the heap itself. It gives you a list of everything allocated by type. You will probably see the object you are allocating excessively, from there you can bring up an allocation graph for that type or that range of time. This will show what functions allocated those objects.

Here's a random blog entry that has some screenshots and discussion of the CLR Profiler in action. (Not quite what you will be doing with it, but a useful intro if you've never used the CLR Profiler before.)

However: Because you are using XNA, and you generally have to try really hard to get C# to run out of managed memory, you are probably running out of unmanaged memory. Is there somewhere you are not calling Dispose() before you stop using a graphics or sound object you created? I have discussed the details of this a couple of times.

So just be aware that, if you have lots of very tiny objects showing up in the CLR Profiler - they may in fact be using up vast amounts of unmanaged memory.

Community
  • 1
  • 1
Andrew Russell
  • 26,924
  • 7
  • 58
  • 104
  • Ah thanks! You were right, you mentioned in one of your posts about disposing vertex buffers and that seems to have cleared it up (well I can't reproduce it like I was before :) ). There was naother thing I had to change though, I used to use an individual content manager for each screen, I removed that 'feature' and now just use the content manager xna provides components. Before then memory was still being used. So should I have also caleld dispose on the individual content classes when they lost their use? – meds Mar 22 '11 at 08:48
  • 1
    You should `Dispose()` of anything that is `IDisposable`, *that you created*, before you get rid of it (`ContentManager` is `IDisposable`, so you dispose of it, and ***it*** will dispose everything it loaded). I have a whole stack of information on using Content Manager at the end of [this answer](http://gamedev.stackexchange.com/questions/9297/when-should-a-bullet-texture-be-loaded-in-xna/9310#9310). – Andrew Russell Mar 22 '11 at 13:52
  • oh right cool, but one more question (in regards to your answer), you say the ContentManagers may share unmanaged resources such as textures. This makes sense since I recall if I called dispose on one content manager a texture would not be accessible anymore with the error that it has been disposed. If I dispose of the content manager, create a new one and load a texutre the previous disposed will it work fine or will I still get the disposed error? Is it possible to undispose a texture in one contentmanager if another contentmanager which had it loaded has disposed of it? – meds Mar 23 '11 at 00:23
  • @meds: Each instance of ContentManager "owns" everything that it `Load()`s. If you try to load a piece of content multiple times with the one ContentManager, you always get the same object back (it keeps a list). But if you have multiple ContentManagers, they don't know about each other, and each will need to load its own copy of the content the first time you ask for it. Calling `Dispose` or `Unload` on a ContentManager will dispose of everything that it has loaded, but has no effect on any other ContentManagers or content. – Andrew Russell Mar 23 '11 at 07:00
2

You could try Redgate's ANTS Memory Profiler (but it costs) and I'm not sure about using it with WP7 but it's for C#.

There is a free trial so you might be able to use that to help locate the problem.

Tony
  • 9,672
  • 3
  • 47
  • 75
1

Eqatec have a profiler which works with WP7. It's not a memory profiler, but I'd give that a try to see what it shows up. It may help point you in the right direction.

Matt Lacey
  • 65,560
  • 11
  • 91
  • 143
1

The coding4fun toolkit contains a Memory Counter that helps track memory usage of your application. Here's the documentation and an article demonstrating its use.

Praetorian
  • 106,671
  • 19
  • 240
  • 328
1

Use the CLR Profiler for the .NET Framework 2.0. It's not supported in XNA 4.0 by default, but Dave on Crappy Coding has a workaround.

Empyrean
  • 1,823
  • 12
  • 10
0

The one I use is Mono profiler. It has various options; the simplest usage is

mono --profile=log program.exe

And then, after program.exe would exit, it'd leave a profiler file (output.mlpd by default), and to read the gathered information use:

mprof-report output.mlpd

E.g. I do mprof-report output.mlpd | vim -.

By default it collects a bunch of different informations. At the very beginning of the output (given default settings) you will see the table of functions sorted by «allocated» column, e.g. a snip:

Allocation summary
  24      Bytes      Count  Average Type name
  25    7357392     306558       24 System.IntPtr
  26    6677904     139123       48 System.Collections.ArrayList.ArrayListEnumeratorSimple
  27    5842736     136185       42 Mono.Unix.Native.Syscall._pollfd[]
  28    3078176      49566       62 System.Byte[]
  29    2574504      38057       67 System.String
  30     908320      14803       61 System.Int32[]
  31     719984       5294      136 Mono.Globalization.Unicode.SortKeyBuffer

Its advantages out of my mind:

  • It is crossplatform, so you could easily profile .net RAM allocations on GNU/Linux and Mac either.
  • It is developed by creators and largest users of .net — Microsoft. Earlier it was developed by Xamarin, but MS bought them, and now they mentioned on the main Mono page.
Hi-Angel
  • 4,933
  • 8
  • 63
  • 86
  • Is there any way to see References in Mono profiler? I don't see it mentioned anywhere. Knowing what references are being held is important to trying to diagnose lost memory the GC can't clean up because of inadvertent references holding the data. – JamesHoux Nov 25 '18 at 14:45
  • Sorry, can't comment on this one. I actually didn't work with .net-like tech for 2 years *(which I'm happy with, for various reasons)*, so don't even have the environment for experimenting with the profiler. – Hi-Angel Nov 25 '18 at 15:10