3

Visual Studio 2013 can show a column for inclusive size (which includes size of child objects) - http://blogs.msdn.com/b/visualstudioalm/archive/2013/10/16/net-memory-analysis-enhancements-in-visual-studio-2013.aspx

DebugDiag's memory analysis reports currently only shows object size without including child objects. Is there a way to make DebugDiag include size of child objects in its report?

What do you suggest is a good way to generate such a report for .NET 4.0 since Visual Studio only supports analyzing .NET 4.5 crash dumps

inclusive size

sgarg
  • 2,340
  • 5
  • 30
  • 42
  • It already includes the size of child objects, as well explained in the blog post. You must have some other kind of definition for "child object", impossible to guess what it might mean. Use a decent memory profiler to get more info. – Hans Passant Sep 15 '14 at 14:03
  • 1
    @HansPassant: Visual Studio includes child objects. DebugDiag doesn't. – Thomas Weller Sep 18 '14 at 12:26

1 Answers1

4

DebugDiag

DebugDiag 2 has totally been rewritten and is now a set of executables (EXE and DLL). It is no longer a set of scripts which you could easily modify to include additional information that you want to be there.

The output of DebugDiag is simiar to what you see in WinDbg+SOS's !dumpheap -stat output:

...
575a4518    11547       560508 System.Object[]
575d37b8       91       892344 System.Byte[]
575d2ee4     3488       927512 System.Int32[]
575d0d48    72920      6939284 System.String
Total 120639 objects

Other approaches

SOS !do <address> gives only the size without children, but there is SOS !objsize <address>, which seems to include children (can't cross check with Visual Studio 2013, only have 2012):

0:008> !do 0b938584 
Name: SomeClass
MethodTable: 08947c0c
EEClass: 08956c38
Size: 292(0x124) bytes
...

0:008> !objsize 0b938584 
sizeof(0b938584) =        11728 (      0x2dd0) bytes (SomeClass)

To do that for all objects on the heap, you can execute !objsize for each object in a loop:

.foreach (address {!dumpheap -short}) {!objsize ${address}}

The only command I know that lists property values recursively is SOSEX's !mdt <address> -r, but it will not output the size.

Analyzing root objects only with Pykd

Starting point for a Pykd script:

0:000> .loadby sos clr; .loadby sos mscorwks
0:000> .load <full path>\sosex.dll
0:000> .load <full path>\pykd.pyd
0:000> !pycmd
>>> gch = dbgCommand("!gch")
>>> lines = gch.split('\n')
>>> for line in lines: dprint(dbgCommand("!objsize "+line[34:50]))
...

Press Enter after ... appears. Note that [34:50] this might need to be adapter for 32 bit.

Thomas Weller
  • 55,411
  • 20
  • 125
  • 222
  • where are you writing the foreach script? Inside windbg? – sgarg Sep 18 '14 at 15:53
  • @sgarg: Yes, start WinDbg, attach to the process, load the debugging extension for .NET (`.loadby sos mscorwks;.loadby sos clr`), then type `.foreach ...`. – Thomas Weller Sep 18 '14 at 20:00
  • Is there a way to traverse just roots in SOS? I don't want to traverse every object in the heap. – sgarg Sep 19 '14 at 13:30
  • I can't get SOS `!FindRoots` to work. SOS `!gcroot
    ` lists roots of the object, but the output can hardly be used to perform anything else, since it's quite unpredictable. SOSEX `!gch` looks better, but also does not have a *short* option and will cause problems because it outputs string values separated by space. Conclusion: non of the built-in functions seem to be appropriate.
    – Thomas Weller Sep 19 '14 at 14:31
  • With PYKD it could be possible to parse the output of SOSEX `!gch`. Another option could be writing the output of `.foreach` into a file, import to Excel and sort by size. Some of the root objects must be the biggest objects, because they reference everything else. – Thomas Weller Sep 19 '14 at 14:33
  • @sgarg: I added a small REPL example combining the power of Pykd and SOSEX `!gch`. – Thomas Weller Sep 19 '14 at 14:57
  • Thank you! I'm trying out the methods you listed. – sgarg Sep 19 '14 at 15:34