Where does the difference between ".NET, total" and ".NET, used" come from?

Analyzing .NET Azure App Service memory dump in dotMemory I see 5GB as ".NET, total" and 200mb as ".NET, used". Looking at the definitions of those 2 I read that Total includes Used and Free. Can dotMemory help me understand why the process has so much Free Memory exactly?

The reason I'm asking is my Azure App Service reports a high Private Bytes consumption for the app, I got the dump to analyze but stuck with the above finding - dotMemory can only explain where 4% of those 5GB come from.

Can I assume ".NET, total" maps 1 to 1 to Private Bytes or Committed Memory? If so, could I be dealing with a situation my service, at some time, indeed allocated 5GB of Managed memory, then it was GC'ed but the Private Bytes just didn't change and I somehow need to collect the dump earlier than I did prior the objects were GC'ed?

I'm looking for any hints which could help me leveraging dotMemory to find the root cause of my process allocating so much memory. I'm using the version 2021.2.2.

1 comment


dotMemory snapshot contains information about Total, .NET Total and .NET Used memory values.

Total memory consists of "unmanaged" memory and ".NET, total" memory. dotMemory uses PROCESS_MEMORY_COUNTERS.PagefileUsage to get this value: https://docs.microsoft.com/en-us/windows/win32/api/psapi/ns-psapi-process_memory_counters?redirectedfrom=MSDN Usually, this size is similar to Windows Task Manager's Commit size: the amount of memory requested by a process. 

Unmanaged memory is memory allocated outside of the managed heap and not managed by Garbage Collector. Generally, this is the memory required by .NET CLR, dynamic libraries, graphics buffer, and so on. This part of memory cannot be analyzed in dotMemory.

.NET, total is the amount of memory in the managed heap used by the app including free space between allocated objects. .NET, total = ".NET, used" + free memory. Free memory may be reserved by CLR to perform future allocations faster. You can't affect this CLR behavior. Anyway, free memory should be released in case of lack of resources.

".NET, used" is the amount of memory in the managed heap used by the app excluding free space. This is the only part of memory .NET allows you to work with. You can get all these objects in dotMemory snapshot.

Could you please open snapshot and find "Heap Fragmentation" section on "Inspections" view? Please make a screenshot of all presented heaps. Also please make a screenshot of "Generations" view. These views can probably show where the free memory actually is.



Please sign in to leave a comment.