10

EDIT: The bounty's expired, but if the community would like to award it to someone, then I choose Raful Chizkiyahu.


I have a memory leak in one of my C# Winforms programs, and I'd like to graph its memory usage over time to get a better understanding of what might be causing the leak. Problem is, none of the usual memory diagnostic commands match up with what the Task Manager is claiming as its consumed memory for that process. I assumed this was perhaps due to the app using unsafe/unmanaged code not being included in the total.

So to try and drill deeper, I created a new Winforms app, very simple, with just a timer to report the memory usage in realtime. I use 5 labels, each with various functions (mostly found from here): Environment.WorkingSet, GC.GetTotalMemory(false), GC.GetTotalMemory(true), Process.GetCurrentProcess().PrivateMemorySize64 and Process.GetCurrentProcess().WorkingSet64.

Surprisingly (or maybe not so, sigh), I still can't get any of these five numbers to match up with the Windows 10 Task Manager. Here's a screenshot:

pic

So what I'm basically looking for is that 5.1MB number. How do I sneakily extract that hidden number from the .NET framework?

Here's the code I have in the Timer tick function:

private void timer1_Tick(object sender, EventArgs e)
{
    //Refresh();
    label1.Text = "Environment.WorkingSet: " +  Environment.WorkingSet ;
    label2.Text = "GC.GetTotalMemory(false): " +    GC.GetTotalMemory(false) ;
    label3.Text = "GC.GetTotalMemory(true): " + GC.GetTotalMemory(true) ;
    Process proc = Process.GetCurrentProcess();
    label4.Text = "proc.PrivateMemorySize64: " +    proc.PrivateMemorySize64 ;
    label5.Text = "proc.WorkingSet64: " +       proc.WorkingSet64 ;
    proc.Dispose();
}

As might be evident, I tried with and without the Refresh() command to no avail.


EDIT: The bounty's expired, but if the community would like to award it to someone, then I choose Raful Chizkiyahu.

Dan W
  • 3,520
  • 7
  • 42
  • 69
  • 2
    Do yourself a favor and don't pay too much attention to TaskManager, it's not reliable .Have a look at dotMemory or try to use Visual Studio's performance profiler or sysinternal tools or something similar. See also https://stackoverflow.com/questions/134086/what-strategies-and-tools-are-useful-for-finding-memory-leaks-in-net – George Vovos May 28 '20 at 09:08
  • Not directly related to your question, but in case what you are experiencing is in fact a managed memory leak, [this article](https://snede.net/hunting-net-memory-leaks-with-windbg/) shows you how windbg and the SOS extension can help you pinpoint the source of the leak. I've applied the technique twice and on both cases I was able to diagnose the problem. – BlueStrat May 29 '20 at 01:34

3 Answers3

6

The windows task manager is showing only the memory that actually on the RAM and the process memory is including the pages (on the disk ) that the reason the process memory can be bigger from the actual RAM on your machine

Raful Chizkiyahu
  • 364
  • 2
  • 15
  • If true, that's incredibly misleading of Microsoft. I find it hard to believe they would limit the reporting in that way when it would be trivial to give the total, or individual paging / RAM usage. – Dan W Jun 03 '20 at 18:40
  • in the task manager, you can see the committed the cached and paged pool per system if you what to now per app you see how match memory app requested from the system not where the system save the memory (l1 l2 l3 ram disk ) – Raful Chizkiyahu Jun 04 '20 at 13:05
  • Ah! Are you referring to the "Details" tab? If so, can you add that to your answer? It looks like I can add more columns, and I got [this result](https://i.imgur.com/TSMzHHi.png). As you can see the `proc.WorkingSet64` figure in VS seems to correspond to the "Working set (memory)" in the Task Manager. `Environment.WorkingSet` also seems close, so which is the best 'true' memory value to pick out of that and `proc.WorkingSet64`? I'm also not sure what the 19,364 KB number equivalent is in VS. – Dan W Jun 04 '20 at 19:24
  • I was intending to probably award you the bounty, but was just waiting closer towards the end. Looks like I missed the deadline. Anyway, your answer was the earliest (and I think) the most appropriate answer. So just a quick note to say Thank You. – Dan W Jun 05 '20 at 12:21
1

i've noticed that Visual studio debugging tools report higher memory usage than task manager in most cases while the task manager only reports the usage of RAM the debugging tools in VS will take into account everything like pagefiles...etc

i think they would be more reliable

Massaynus
  • 322
  • 2
  • 9
  • Thanks, I'm closing in gradually. Take a look at my latest comment to Raful Chizkiyahu. – Dan W Jun 04 '20 at 19:26
0

You need better tooling, TaskManager will only give you approximate memory usage at a certain moment.

If you suspect a memory leak, the tried and true method is to take memory dumps(snapshots) of the application.

A snapshot should be taken at application startup, then at subsequent intervals. If memory rises slowly you will have to wait a bit between each snapshot. You can then compare the snapshots. This method allows you to analyze and compare object allocations, object counts, even unmanaged memory.

Microsoft has written a guide for the Memory Usage tool integrated into Visual Studio. In most cases this should suffice in identifying the leak.

If you find the integrated tooling limited, have a look at this SO question and others linked in the sidebar.

Alexander Pope
  • 1,134
  • 1
  • 12
  • 22
  • Thanks, that's useful to know, but first I need to track what type of memory stat (out of the ten or so) to look at, and from there, see the behavior of the memory usage and under what circumstances it occurs (it's not easily reproducible, and sometimes the memory leak doesn't occur). So first, I'll write a simple logger and see if I can trace patterns of when the leak starts to occur. – Dan W Jun 04 '20 at 19:30