title: WinDbg not telling me where my string is rooted
body: <p>I am trying to track down why a string is stored so long in my application, and eating up an excessive amount of memory. I have a Windows Service which runs regularly. </p>
  
  <p>It reads data from a database (in the form of a DataSet) and then does some processing - all managed .NET. </p>
  
  <p>The Windows Service is triggered once every 5 or so minutes, which does some cross-referencing. Each row of the DataSet shouldn't take much more than a second - worst case!</p>
  
  <p>At one stage the Private Bytes > 1.2GB, even though there was no data available to process. There are no global variables, and all processing is done within individual methods.</p>
  
  <p>I took a snapshot and processed with WinDbg. Here are the results:</p>
  
  <pre><code>0:000&gt; !dumpheap -min 85000
   Address       MT     Size
  02027f40 00166620   101432 Free
  28411000 79330b24 536870936     
  48c11000 79333594 226273040     
  08411000 79330b24 452546504     
  total 4 objects
  Statistics:
        MT    Count    TotalSize Class Name
  00166620        1       101432      Free
  79333594        1    226273040 System.Byte[]
  79330b24        2    989417440 System.String
  Total 4 objects
  </code></pre>
  
  <p>And so we want to find the 2 strings that are causing the problem:</p>
  
  <pre><code>0:000&gt; !dumpheap -mt 79330b24  -min 85000
   Address       MT     Size
  28411000 79330b24 536870936     
  08411000 79330b24 452546504     
  total 2 objects
  Statistics:
        MT    Count    TotalSize Class Name
  79330b24        2    989417440 System.String
  Total 2 objects
  </code></pre>
  
  <p>Now I want to find out where these 2 are located, but when I use !gcroot, it doesn't return any results:</p>
  
  <pre><code>0:000&gt; !gcroot 28411000 
  Note: Roots found on stacks may be false positives. Run "!help gcroot" for
  more info.
  Scan Thread 0 OSTHread 2970
  Scan Thread 2 OSTHread 2ab4
  Scan Thread 3 OSTHread 12ac
  Scan Thread 4 OSTHread 1394
  Scan Thread 5 OSTHread 1b78
  Scan Thread 8 OSTHread 1364
  Scan Thread 9 OSTHread 226c
  Scan Thread 10 OSTHread 1694
  0:000&gt; !gcroot 08411000 
  Note: Roots found on stacks may be false positives. Run "!help gcroot" for
  more info.
  Scan Thread 0 OSTHread 2970
  Scan Thread 2 OSTHread 2ab4
  Scan Thread 3 OSTHread 12ac
  Scan Thread 4 OSTHread 1394
  Scan Thread 5 OSTHread 1b78
  Scan Thread 8 OSTHread 1364
  Scan Thread 9 OSTHread 226c
  Scan Thread 10 OSTHread 1694
  </code></pre>
  
  <p>I don't understand what I am doing wrong, or why the string's root cannot be found. I have done !do on it, and it just says the strings are unprintable:</p>
  
  <pre><code>0:000&gt; !do 28411000 
  Name: System.String
  MethodTable: 79330b24
  EEClass: 790ed65c
  Size: 536870930(0x20000012) bytes
   (C:\WINDOWS\assembly\GAC_32\mscorlib\2.0.0.0__b77a5c561934e089\mscorlib.dll)
  String: &lt;String is invalid or too large to print&gt;
  
  Fields:
        MT    Field   Offset                 Type VT     Attr    Value Name
  79332d70  4000096        4         System.Int32  0 instance 268435457 m_arrayLength
  79332d70  4000097        8         System.Int32  0 instance 226273026 m_stringLength
  79331804  4000098        c          System.Char  0 instance       57 m_firstChar
  79330b24  4000099       10        System.String  0   shared   static Empty
      &gt;&gt; Domain:Value  00159f38:01021198 &lt;&lt;
  79331754  400009a       14        System.Char[]  0   shared   static WhitespaceChars
      &gt;&gt; Domain:Value  00159f38:010217d4 &lt;&lt;
  </code></pre>
  
  <p>And</p>
  
  <pre><code>0:000&gt; !do 08411000 
  Name: System.String
  MethodTable: 79330b24
  EEClass: 790ed65c
  Size: 452546502(0x1af94fc6) bytes
   (C:\WINDOWS\assembly\GAC_32\mscorlib\2.0.0.0__b77a5c561934e089\mscorlib.dll)
  String: &lt;String is invalid or too large to print&gt;
  
  Fields:
        MT    Field   Offset                 Type VT     Attr    Value Name
  79332d70  4000096        4         System.Int32  0 instance 226273243 m_arrayLength
  79332d70  4000097        8         System.Int32  0 instance 226273242 m_stringLength
  79331804  4000098        c          System.Char  0 instance       45 m_firstChar
  79330b24  4000099       10        System.String  0   shared   static Empty
      &gt;&gt; Domain:Value  00159f38:01021198 &lt;&lt;
  79331754  400009a       14        System.Char[]  0   shared   static WhitespaceChars
      &gt;&gt; Domain:Value  00159f38:010217d4 &lt;&lt;
  </code></pre>
  
  <p>Can someone help please?</p>
  
  <p>--</p>
  
  <p>Update:</p>
  
  <p>!eeheap -gc</p>
  
  <pre><code>Number of GC Heaps: 1
  generation 0 starts at 0x01175764
  generation 1 starts at 0x011756dc
  generation 2 starts at 0x01021000
  ephemeral segment allocation context: none
   segment    begin allocated     size
  01020000 01021000  0117b770 0x0015a770(1419120)
  Large object heap starts at 0x02021000
   segment    begin allocated     size
  02020000 02021000  02040d88 0x0001fd88(130440)
  28410000 28411000  48411018 0x20000018(536870936)
  48c10000 48c11000  563db710 0x0d7ca710(226273040)
  08410000 08411000  233a5fc8 0x1af94fc8(452546504)
  Total Size  0x488d9be8(1217240040)
  ------------------------------
  GC Heap Size  0x488d9be8(1217240040)
  </code></pre>
  
  <p>Update 2: I removed the references to XML as this particular program doesn't process XML - my bad.</p>
  
  <hr>
  
  <p>Update 3:</p>
  
  <p>Here is the results of using psscor2.dll</p>
  
  <pre><code>0:000&gt; !heapstat -inclUnrooted
  Heap     Gen0         Gen1         Gen2         LOH
  Heap0    32780        68316        1324728      1217845888  
  
  Free space:                                                 Percentage
  Heap0    12           67212        59764        101640      SOH:  8% LOH:  0%
  
  Unrooted objects:                                           Percentage
  Heap0    2684         1104         757416       1217715448  SOH: 53% LOH: 99%
  </code></pre>