+1  A: 

Download MemProfiler from Scitech. It has a 14 day trial version.

The problem you report is often due to views/resources which cannot be disposed due to having a root in the heap. A common cause is not unwiring event handlers.

Mitch Wheat
Thanks Mitch. Just played around with MemProfiler a bit and found a LOT of byte[] from "MergedDictionaries" (a WPF thing). Trying to fix that now. This is not all but something, thank you!
andyhammar
+3  A: 

Just because your application uses a lot of memory doesn't necessary mean that you have a memory leak. From the information in your question it is difficult to assert what may be wrong.

When troubleshooting managed memory leaks with WinDbg I do the following:

  • Get an overview of the heap usage with !eeheap (this reports the heap usage and not the stack as you mention - each stack has a default size of 1 MB, so unless you have changed this there's no way you can use 100 MB on the stack)

  • Do a !dumpheap -stat to find out what is on the heap. Chances are that if you have a memory leak the guilty type(s) will be among the top consumers. To get an idea of how heap usage develops you can resume your application, break it a little later and then repeat the !dumpheap -stat command.

  • If you find any types with more instances than you would except, list those using !dumpheap -mt <MT of type>. This will list all the instances of the particular type. Pick random instances and check roots using the !gcroot command. This will tell you what keeps the instances in question alive. If there are no root these instances will be collected at some point.

UPDATE to reply to your comments:

The managed heap is only a part of a managed application's memory footprint. Remember, that a .NET application is really an application inside another application - the host process, which loads the CLR, which in turn loads your application. So before your application starts to use any memory the CLR has already taken a fair share. On top of that .NET applications store both MSIL code and JIT compiled code as part of the foot print. The CLR takes up space for various bookkeeping stuff as well (e.g. the CLR creates two additional AddDomains for internal use).

The numbers you give do not strike me as over the top, but since I don't know your application it is hard to say if the are excessive.

100 MB on the managed heap could be okay, depending on what your application is doing. Did you check the heap? And if so what did you find?

Brian Rasmussen
Thanks Brian! With a heapsize of 139 596 684, my biggest mem-users are: 1) System.Byte[] (14949 items, mem: 32 217 996), 2) System.String (475 010 items, mem: 31 016 248) and 3) System.Windows.Markup.BamlDefAttributeKeyStringRecord (items: 230 845 mem: 11 080 560). The byte[]s are from reading images from from disk and creating BitmapSources. The strings I don't know, probably a WPF thing...
andyhammar
Another sample: total committed: 178 Mb, private bytes: 538 Mb. Digging further...
andyhammar
+1  A: 

You might like to try reading this article in the latest MSDN magazine. It goes into detail on how to use VADump to understand more about where a process's memory is devoted.

You can download VADump here: http://go.microsoft.com/fwlink/?LinkId=149683

To break down the managed heap, you might try a memory profiler. I personally like JetBrains dotTrace.

Drew Noakes
Thanks Drew, vadump didn't work for me yesterday but I tried it now - reports numbers that don't match eeheap. I've posted a comment to my question.
andyhammar
+2  A: 

I had a similar problem in a WPF application, and used UMDH to track where the native memory was being allocated. (Note that it is usually helpful to set _NT_SYMBOL_PATH to get good stack traces from the OS components.

The logs showed that almost all of the memory was being allocated in the video driver. I found that the driver was more than a year out of date; I installed the latest version from the manufacturer's website and that fixed the problem.

Bradley Grainger
A: 

One answer: It goes to way too many merged ResourceDictionaries (a WPF thing)

Details: To be able to see the design in design-time in Blend and VS, we used to merge our theme resource dictionary on most xaml pages. This caused a copy of all resources to be loaded for each control, more info can be read here: [WPF Disciples][1]

So the only place I merge them now is App.xaml.cs:

<Application.Resources>
  <ResourceDictionary>
    <ResourceDictionary.MergedDictionaries>
      <ResourceDictionary 
        Source="pack://application:,,,/Company.Themes;Component/AppTheme.xaml"/>
    </ResourceDictionary.MergedDictionaries>
  </ResourceDictionary>
</Application.Resources>

Results: (running the app through some pages with an automatic GUI test)

Before:

  • After app load: 63 Mb
  • After app usage: 177 Mb

After:

  • After app load: 53 Mb
  • After app usage: 97 Mb

I'll post more answers as I find them! (I thought it would be easiest for readers to see my finding as separate answers instead of replys to comments - good?)

[1]: ref: http://groups.google.com/group/wpf-disciples/web/wpf-and-xaml-coding-guidelines?pli=1

andyhammar