How do I find where memory is being used up in C#?
Asked Answered
L

6

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!

Laoag answered 21/3, 2011 at 22:41 Comment(0)
S
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.

Scrouge answered 22/3, 2011 at 7:28 Comment(4)
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?Laoag
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.Scrouge
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?Laoag
@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.Scrouge
D
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.

Deathlike answered 21/3, 2011 at 22:44 Comment(0)
L
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.

Luigiluigino answered 21/3, 2011 at 23:3 Comment(0)
T
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.

Tideland answered 21/3, 2011 at 23:45 Comment(0)
S
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.

Siftings answered 22/3, 2011 at 2:10 Comment(1)
The CLR Profiler for .NET 4.0 is now available. See my answer.Scrouge
K
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.
Kalevala answered 28/7, 2016 at 10:22 Comment(2)
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.Jolley
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.Kalevala

© 2022 - 2024 — McMap. All rights reserved.