microsoft / clrmd

Microsoft.Diagnostics.Runtime is a set of APIs for introspecting processes and dumps.
MIT License
1.05k stars 256 forks source link

Cannot calculate memory size correctly, from CLR Objects .Size property #1236

Closed PanosGreg closed 8 months ago

PanosGreg commented 8 months ago

I'm trying to find out the amount of memory used by each .NET type for a specific process.

First I attach to that process based on its Process ID and I get the Runtime from that. Then I'm grouping all the objects that I get from Heap.EnumerateObjects() based on their types And finally I calculate the sum of the .Size property from each object on each group separately.

The problem is that I'm getting numbers that are way larger than expected. Here's an example output:

Memory  Count Type
------  ----- ----
82GB        6 System.Runtime.CompilerServices.ConditionalWeakTable<System.Object
14.9GB   3406 System.Object[]
3.9GB    4218 System.Int32[]
933MB  106652 System.String
11.5MB  89889 System.Management.Automation.PSObject

The above is from a PowerShell v7.4.1 process which according to Task Manager takes approx. 145MB of RAM whereas the PrivateMemorySize64 property of the same, from System.Diagnostics.Process shows 152MB (so both of these are pretty close, thus I assume they are correct)

But the memory sums of the .NET types are completely off. What am I doing wrong here ?

Here's the PowerShell function I wrote which gives the above result as shown, which uses all the aformentioned methods. https://gist.github.com/PanosGreg/ae1b4bb806f8b6eb5a66479056fffafb

PanosGreg commented 8 months ago

Apologies, I think I've found the issue. I was using the .AttachToProcess() method, whereas I should've been using the .CreateSnapshotAndAttach() method, as per the Getting Started documentation

The numbers now seem much more inline. Here's a sample execution in PowerShell

C:\> Add-Type -Path (dir 'C:\RuntimeDiagnostics\*\lib\netstandard2.0\*.dll').FullName
C:\> . C:\Scripts\Get-RuntimeDiagnostics.ps1
C:\> 
C:\> Get-RuntimeDiagnostics -NumberOfItems 5

Memory  Count Type
------  ----- ----
10.7MB 116989 System.String
2.2MB   54401 System.Collections.Concurrent.ConcurrentDictionary<System.String, System.Management.Automation.CommandTy…
1.45MB  45349 System.Management.Automation.Language.InternalScriptExtent
861KB    1120 System.Collections.Concurrent.ConcurrentDictionary<System.String, System.Management.Automation.CommandTy…
728KB    6996 System.Reflection.RuntimeMethodInfo

I'll close the issue.

PanosGreg commented 8 months ago

Closing this issue