How to use WinDBG to track down .net out of memory exceptions?
Asked Answered
A

1

7

I need to track down the reason for out of memory (OOM) exceptions in a .NET application. Using perfmon, the app crashes with an OOM when using relatively low memory (500-700mb), so I'm assuming some sort of heap fragmentation.

After researching it looks like WinDBG is the tool to use to track this kind of problem down. I've set up DebugDiag on the server running the processes. I've also managed to load the dump from DebugDiag into WinDBG, hook up the symbol server and my own private symbol files and it all seems to work - I can run commands like !clrstack and !dumpheap -stat and I'll see my class names listed.

The problem I have now is I don't know how to approach the problem of tracking down where the fragmentation is. WinDGB has a lot of commands with a lot of different flags and options and I'm not sure which ones I should be using. I couldn't track down a good tutorial on what to do either - most are really basic around getting WinDBG up and running.

Could someone point me in the right direction?

Abaft answered 1/10, 2014 at 13:30 Comment(1)
blogs.msdn.com/b/paullou/archive/2011/06/28/…Parliamentarianism
B
23

Here's the graph that I use for deciding about .NET OutOfMemoryExceptions:

.NET out of memory decision tree

For the !u part, I know two options so far. The first is the creation of a big array of objects. See How to identify array type for details. The second is throwing an OutOfMemoryException directly, which you would identify like this:

0:000> .symfix d:\debug\symbols

0:000> .reload

0:000> ~#s

0:000> .loadby sos mscorwks; *** Use clr if .NET4

0:000> !pe
Exception object: 025d07d8
Exception type: System.OutOfMemoryException
Message: Nicht genügend Speicher verfügbar, um das Programm weiter auszuführen.
InnerException: <none>
StackTrace (generated):
    SP       IP       Function
    0024EC90 004F008D OOM1!OOM1.Program.Main()+0x1d

0:000> !u 004F008D 
Normal JIT generated code
OOM1.Program.Main()
Begin 004f0070, size 1e
004f0070 50              push    eax
004f0071 b96c0fcb78      mov     ecx,offset mscorlib_ni+0x270f6c (78cb0f6c) (MT: System.OutOfMemoryException)
004f0076 e8a11ff1ff      call    0040201c (JitHelp: CORINFO_HELP_NEWSFAST)
004f007b 890424          mov     dword ptr [esp],eax
004f007e 8bc8            mov     ecx,eax
004f0080 e8f314c078      call    mscorlib_ni+0x6b1578 (790f1578) (System.OutOfMemoryException..ctor(), mdToken: 0600036a)
004f0085 8b0c24          mov     ecx,dword ptr [esp]
004f0088 e84a615179      call    mscorwks!JIT_Throw (79a061d7)
>>> 004f008d cc              int     3

The call to call System.OutOfMemoryException..ctor() is a new OutOfMemoryException() in C# and call mscorwks!JIT_Throw is the throw keyword.

Beaudoin answered 1/10, 2014 at 21:1 Comment(1)
fantastic! love the flow chartAbaft

© 2022 - 2024 — McMap. All rights reserved.