title: Contradictory reporting of total Process memory usage in C# Winforms app
body: <p><strong>EDIT: The bounty's expired, but if the community would like to award it to someone, then I choose Raful Chizkiyahu.</strong></p>
  
  <hr>
  
  <p>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.</p>
  
  <p>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 <a href="https://stackoverflow.com/q/750574">from here</a>): <code>Environment.WorkingSet</code>, <code>GC.GetTotalMemory(false)</code>, <code>GC.GetTotalMemory(true)</code>, <code>Process.GetCurrentProcess().PrivateMemorySize64</code> and <code>Process.GetCurrentProcess().WorkingSet64</code>.</p>
  
  <p>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:</p>
  
  <p><img src="https://i.stack.imgur.com/c1UO6.png" alt="pic"></p>
  
  <p>So what I'm basically looking for is that 5.1MB number. How do I sneakily extract that hidden number from the .NET framework?</p>
  
  <p>Here's the code I have in the Timer tick function:</p>
  
  <pre><code>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();
  }
  </code></pre>
  
  <p>As might be evident, I tried with and without the <code>Refresh()</code> command to no avail.</p>
  
  <hr>
  
  <p><strong>EDIT: The bounty's expired, but if the community would like to award it to someone, then I choose Raful Chizkiyahu.</strong></p>