views:

444

answers:

2

Is there a way in the .NET API to iterate on the managed objects present in the managed heap?

We would like to add a routine at some points in our program which checks the presence of some objects in the managed heap.

+2  A: 

You'd need to use the debugging/profiling API to do this - which I wouldn't recommend for a "normal" application.

Jon Skeet
+2  A: 
  1. Install "Debugging Tools for Windows".

    a. Link: http://www.microsoft.com/whdc/devtools/debugging/default.mspx

    b. You’ll be using WinDbg.EXE, the native Windows debugger, and SOS.DLL (a.k.a. "Son of Strike"), the WinDbg extension for managed code.

    c. The default installation location is "C:\Program Files\Debugging Tools for Windows".

  2. Run your managed process.

  3. Run WinDbg and click "File -> Attach to a Process…"

  4. Select your process from the list.

  5. WinDbg will automatically break (stop) execution on attaching to your process.

  6. Type ".load sos.dll" (yes, with the preceding ‘.’) at WinDbg’s command line to load Son of Strike.

  7. Type "!help" to see the list of commands/features Son of Strike offers.

  8. Type "!traverseheap –xml heap.xml" to dump the heap of your process to heap.xml in WinDbg’s directory (e.g., C:\Program Files\Debugging Tools for Windows").

    a. Traversing and dumping the heap to a file can take a very, very long time. WinDbg will post "BUSY" to its status and print "."-s to indicate progress.

    b. In general, heap.xml is structured as follows:

    < Type IDs >

    ...

    < Objects >

    Each class (type) holds an ID and each object holds its type ID, managed address, and size.

  9. Use findstr (Command Prompt) against heap.xml to grep your way through the heap, and WinDbg to dump objects.

    a. Example: Find the type ID of the DataTable class.

    • findstr "DataTable" heap.xml

      Output: < type id="1002" name="System.Data.DataTable"/ >

    b. Example: Find all DataTable objects.

    • findstr "typeid=\"1002\"" heap.xml

      Output: < object address="0x0137ECD8" typeid="1002" size="296" >

    c. Example: Dump a DataTable object.

    • (In WinDbg) !dumpobj 0137ecd8

    d. Example: Dump a member object. The address of a member object is stored in the "Value" field of the member’s containing object dump.

    • !dumpobj < "Value" >

.

Add, if you want to track large object allocations, here's how to break in the CLR on an LOH allocation. On breaking, hit 'k' to see the callstack.

Run WinDbg and attach as below.

  1. Add Microsoft's symbol server to the symbol path:
  2. Reload symbols:
    • .reload
  3. Reload the runtime shim:
    • .reload /f mscorwks.dll
  4. Break on UP allocations:
    • bp mscorwks!WKS::gc_heap::allocate_large_object
  5. Break on MP allocations:
    • bp mscorwks!SVR::gc_heap::allocate_large_object
  6. Confirm breakpoints:
    • bl
  7. Resume:
    • g
Bob