.netprofilingdotmemory

Take .NET snapshots without forcing GC collection


I have an app that's deployed in production and there are times where it starts consuming a lot of RAM. To be able to profile and figure out why memory is getting consumed this much at a point, I figured I'd use dotMemory CLI profiling tools for that.

I attach dotMemory to the process and then use ##dotMemory["get-snapshot", {pid:12345}].

However, when the app (in this case a Web API in .NET 4.5) rises from 1.7GB (standard) to 2.5GB or further, once I perform get-snapshot, dotMemory seems to force a garbage collection, which ultimately clears the taken memory back to cca 1.7GB. Considering the fact that it would normally never go down without a restart, dotMemory is not very helpful because the snapshots I get are after the garbage collection, meaning I have no way of figuring out what took that much of RAM.

Is there a workaround for this or another tool that I can perhaps use?


Solution

  • You can get Windows memory dump using process explorer or .NET memory dump using dotnet.exe depending on under what .NET framework version you app is running. Then you can analyze it in dotMemory or any other suitable application.

    But I have an addition. dotMemory forces standard .NET garbage collecting (GC) process and droping the memory consumption by your app means that references on objects were already cleared but no GC was performed. Most probably it means that there is enough memory on the computer and GC algorithm decided that it's better to not collect the memory for a while. It is optimized for application performance not for keeping memory consumption low with no need. In two words - your case is not a problem, GC in its right to decide when to peform the collecting.