title: How to calculate memory usage as Task Manager does?
body: <p>Ok so I am using WMI (.net/C#) to constantly collect data about a specific process that is running on the machine. I get the data through <a href="https://msdn.microsoft.com/en-us/library/aa394277%28v=vs.85%29.aspx" rel="noreferrer">Win32_PerfFormattedData_PerfProc_Process</a> class. That class has a lot of properties but those that we are interested in are as follows:</p>
  
  <pre><code>  uint64 PageFileBytes;
  </code></pre>
  
  <p>Value, in bytes, that this process has used in the paging file(s). Paging files store pages of memory used by the process that are not contained in other files. Paging files are shared by all processes and lack of space in paging files can prevent other processes from allocating memory.</p>
  
  <pre><code>  uint32 PoolNonpagedBytes;
  </code></pre>
  
  <p>Value, in bytes, in the nonpaged pool, an area of system memory (physical memory used by the operating system) for objects that cannot be written to disk, but must remain in physical memory as long as they are allocated. The PoolNonpagedBytes in Win32_PerfFormattedData_PerfOS_Memory is calculated differently than the PoolPagedBytes property in Win32_PerfFormattedData_PerfProc_Process, so it might not equal the total of PoolPagedBytes for all instances of Win32_PerfFormattedData_PerfProc_Process. This property displays the last observed value only; it is not an average.</p>
  
  <pre><code>  uint32 PoolPagedBytes;
  </code></pre>
  
  <p>Value, in bytes, in the paged pool, an area of system memory (physical memory used by the operating system) for objects that can be written to disk when they are not being used. The PoolNonpagedBytes property in Win32_PerfFormattedData_PerfOS_Memory is calculated differently than the PoolPagedBytes property in Win32_PerfFormattedData_PerfProc_Process, so it might not equal the total of PoolPagedBytes for all instances of Win32_PerfFormattedData_PerfProc_Process. This property displays the last observed value only; it is not an average.</p>
  
  <pre><code>  uint64 PrivateBytes;
  </code></pre>
  
  <p>Current value, in bytes, that this process has allocated that cannot be shared with other processes.</p>
  
  <pre><code>  uint64 VirtualBytes;
  </code></pre>
  
  <p>Current size, in bytes, of the virtual address space that the process is using. Use of virtual address space does not necessarily imply corresponding use of either disk or main memory pages. Virtual space is finite and, by using too much, the process can limit its ability to load libraries.</p>
  
  <pre><code>  uint64 WorkingSet;
  </code></pre>
  
  <p>Maximum number, in bytes, in the working set of this process at any point in time. The working set is the set of memory pages touched recently by the threads in the process. If free memory in the computer is above a threshold, pages are left in the working set of a process even if they are not in use. When free memory falls below a threshold, pages are trimmed from working sets. If they are required, they are then soft-faulted back into the working set before they leave main memory.</p>
  
  <p>I am currently using the <code>WorkingSet</code> field to report the process' memory usage. However that does not align with what Task Manger is showing. I tried with <code>PrivateBytes</code> but that's not "correct" too. The process that the app monitors is a .NET process (if that matters at all) and it gets reported by the app to use at least 100MBs more memory than what Task Manager is showing at the same time.</p>
  
  <p>So the question is what is the "formula" to calculate the best approximation of process' memory usage as shown by Task Manager?</p>
  
  <p><img src="https://i.stack.imgur.com/Zdnwe.png" alt="enter image description here"></p>