title: Analyzing the root cause of OutOfMemoryException in WPF app with WinDbg
body: <p>I'm having some troubles to understand the crash dump and to find what is the root cause of the <code>OutOfMemoryException</code> thrown by the WPF application. The exception is thrown after the application has been run for several hours so this clearly indicates that there is a memory leak.</p>
  
  <p>My first step was to look at <code>!address -summary</code> command :</p>
  
  <pre><code>--- Usage Summary ---------------- RgnCount ------- Total Size -------- %ofBusy %ofTotal
  &lt;unknown&gt;                              2043          58997000 (   1.384 Gb)  71.43%   69.22%
  Heap                                    152           fcc3000 ( 252.762 Mb)  12.74%   12.34%
  Image                                  1050           bc77000 ( 188.465 Mb)   9.50%    9.20%
  Stack                                   699           7d00000 ( 125.000 Mb)   6.30%    6.10%
  Free                                    518           3f6b000 (  63.418 Mb)            3.10%
  TEB                                     125             7d000 ( 500.000 kb)   0.02%    0.02%
  Other                                    12             36000 ( 216.000 kb)   0.01%    0.01%
  PEB                                       1              1000 (   4.000 kb)   0.00%    0.00%
  
  --- Type Summary (for busy) ------ RgnCount ----------- Total Size -------- %ofBusy %ofTotal
  MEM_PRIVATE                            2186          685b7000 (   1.631 Gb)  84.14%   81.53%
  MEM_IMAGE                              1710           f3f3000 ( 243.949 Mb)  12.29%   11.91%
  MEM_MAPPED                              186           46db000 (  70.855 Mb)   3.57%    3.46%
  
  --- State Summary ---------------- RgnCount ----------- Total Size -------- %ofBusy %ofTotal
  MEM_COMMIT                             3366          73fe7000 (   1.812 Gb)  93.52%   90.62%
  MEM_RESERVE                             716           809e000 ( 128.617 Mb)   6.48%    6.28%
  MEM_FREE                                518           3f6b000 (  63.418 Mb)            3.10%
  
  --- Protect Summary (for commit) - RgnCount ----------- Total Size -------- %ofBusy %ofTotal
  PAGE_READWRITE                         1650          5e19e000 (   1.470 Gb)  75.87%   73.52%
  PAGE_EXECUTE_READ                       224           bc42000 ( 188.258 Mb)   9.49%    9.19%
  PAGE_READWRITE|PAGE_WRITECOMBINE         28           439f000 (  67.621 Mb)   3.41%    3.30%
  PAGE_READONLY                           573           3d7b000 (  61.480 Mb)   3.10%    3.00%
  PAGE_WRITECOPY                          214            f8f000 (  15.559 Mb)   0.78%    0.76%
  PAGE_EXECUTE_READWRITE                  265            d0a000 (  13.039 Mb)   0.66%    0.64%
  PAGE_READWRITE|PAGE_GUARD               357            33b000 (   3.230 Mb)   0.16%    0.16%
  PAGE_EXECUTE_WRITECOPY                   55            119000 (   1.098 Mb)   0.06%    0.05%
  
  --- Largest Region by Usage ----------- Base Address -------- Region Size ----------
  &lt;unknown&gt;                                   78d40000           2350000 (  35.313 Mb)
  Heap                                        36db0000            fd0000 (  15.813 Mb)
  Image                                       64a8c000            e92000 (  14.570 Mb)
  Stack                                        4b90000             fd000 (1012.000 kb)
  Free                                        7752f000            1a1000 (   1.629 Mb)
  TEB                                         7ede3000              1000 (   4.000 kb)
  Other                                       7efb0000             23000 ( 140.000 kb)
  PEB                                         7efde000              1000 (   4.000 kb)
  </code></pre>
  
  <p>This shows that the memory is quite high.</p>
  
  <p>Then I'm looking at GC heap size with <code>eeheap -gc</code> command. It shows that the heap is quite big (1.1GB) which indicates that there is a problem within the managed part of the application.</p>
  
  <pre><code>5fc90000  5fc91000  60c7acd4  0xfe9cd4(16686292)
  5a060000  5a061000  5b05e9c0  0xffd9c0(16767424)
  56de0000  56de1000  57ddf1c4  0xffe1c4(16769476)
  57de0000  57de1000  58ddbbbc  0xffabbc(16755644)
  73ff0000  73ff1000  74fe0f5c  0xfeff5c(16711516)
  50de0000  50de1000  51dcfa58  0xfeea58(16706136)
  5b060000  5b061000  5c05ca54  0xffba54(16759380)
  4fde0000  4fde1000  50ddfd8c  0xffed8c(16772492)
  Large object heap starts at 0x03921000
   segment     begin allocated  size
  03920000  03921000  049013d0  0xfe03d0(16647120)
  14850000  14851000  15837380  0xfe6380(16671616)
  178d0000  178d1000  1889a3e0  0xfc93e0(16552928)
  1a1c0000  1a1c1000  1b1abca8  0xfeaca8(16690344)
  40de0000  40de1000  41dc8b48  0xfe7b48(16677704)
  42de0000  42de1000  43827170  0xa46170(10772848)
  54de0000  54de1000  55dd6d18  0xff5d18(16735512)
  Total Size:              Size: 0x448fde94 (1150279316) bytes.
  ------------------------------
  GC Heap Size:            Size: 0x448fde94 (1150279316) bytes.
  </code></pre>
  
  <p>Notice that there are 64 segments and each about (16MB). It seems that there is some data held in the memory and never released.</p>
  
  <p>Next I look at <code>!dumpheap -stat</code>:</p>
  
  <pre><code>65c1f26c   207530     19092760 System.Windows.Media.GlyphRun
  65c2c434   373991     20943496 System.Windows.Media.RenderData
  68482bb0   746446     26872056 MS.Utility.ThreeItemList`1[[System.Double, mscorlib]]
  65c285b4   746448     29857920 System.Windows.Media.DoubleCollection
  64c25d58   299568     32353344 System.Windows.Data.BindingExpression
  6708a1b8  2401099     38417584 System.WeakReference
  67082c2c  1288315     41226080 System.EventHandler
  67046f80  1729646     42238136 System.Object[]
  64c1409c   206969     52156188 System.Windows.Controls.ContentPresenter
  67094c9c   382163     64812664 System.Byte[]
  004b0890      159     65181140      Free
  64c150d0   207806     72316488 System.Windows.Controls.TextBlock
  6708fd04  1498498     97863380 System.String
  6848038c   847783    128775772 System.Windows.EffectiveValueEntry[]
  </code></pre>
  
  <p>As I understand it, there is no a signle object that takes all the memory. The biggest one is just about 122MB. Summing up all the sizes (8500 lines of outputed lines) gives the (1.1GB) of occupied memory. It seems that all the object graph is somehow duplicated and added to the memory and never released.</p>
  
  <p>The <code>!gcroot 6848038c</code> or <code>!gcroot 6708fd04</code> to inspect how EffectiveValueEntry and System.String are reachable, never ends, the stack is soooo big...</p>
  
  <p><code>dumpheap -mt &lt;address&gt;</code> doesn't show me something that srikes me. <code>!finalizequeue</code> shows that there are many objects (more that 2 millions) registered for finalization :</p>
  
  <pre><code>6708a1b8  2401099     38417584 System.WeakReference
  Total 2417538 objects
  </code></pre>
  
  <p>I suspect that the <code>OutOfMemoryException</code> occures when the application tries to duplicate the object graph and allocate new memory, but I cannot find the root cause of it.</p>
  
  <p><strong>Question</strong> How can I drill down to the root of the problem (what other command of windbg can I use to check it). As it seems that not just one object is leaking but the whole object graph.. Am I on the right track or there is something else I'm overlooking ? What are other hypothesis ?</p>