Contradictory reporting of total Process memory usage in C# Winforms app
Asked Answered
V

3

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.

Viscounty answered 25/5, 2020 at 20:14 Comment(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 #134586Schistosomiasis
Not directly related to your question, but in case what you are experiencing is in fact a managed memory leak, this article 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.Funereal
C
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

Clericalism answered 2/6, 2020 at 22:24 Comment(4)
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.Viscounty
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 )Clericalism
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. 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.Viscounty
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.Viscounty
X
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

Xenocrates answered 3/6, 2020 at 11:52 Comment(1)
Thanks, I'm closing in gradually. Take a look at my latest comment to Raful Chizkiyahu.Viscounty
E
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.

Endopeptidase answered 2/6, 2020 at 20:37 Comment(1)
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.Viscounty

© 2022 - 2024 — McMap. All rights reserved.