<p>I'm trying to find out how much memory my own .Net server process is using (for monitoring and logging purposes).</p>

<p>I'm using:</p>

<pre><code>Process.GetCurrentProcess().PrivateMemorySize64
</code></pre>

<p>However, the Process object has several different properties that let me read the memory space used:
Paged, NonPaged, PagedSystem, NonPagedSystem, Private, Virtual, WorkingSet</p>

<p>and then the "peaks": which i'm guessing just store the maximum values these last ones ever took.</p>

<p>Reading through the MSDN definition of each property hasn't proved too helpful for me. I have to admit my knowledge regarding how memory is managed (as far as paging and virtual goes) is very limited.</p>

<p>So my question is obviously "which one should I use?", and I know the answer is "it depends".</p>

<p>This process will basically hold a bunch of lists in memory of things that are going on, while other processes communicate with it and query it for stuff. I'm expecting the server where this will run on to require lots of RAM, and so i'm querying this data over time to be able to estimate RAM requirements when compared to the sizes of the lists it keeps inside.</p>

<p>So... Which one should I use and why?</p>

[{'answer_id': 31164, 'author': 'Lars Truijens', 'author_id': 1242, 'author_profile': 'https://Stackoverflow.com/users/1242', 'pm_score': 5, 'selected': True, 'text': '<p>If you want to know how much the GC uses try:</p>\n\n<pre><code>GC.GetTotalMemory(true)\n</code></pre>\n\n<p>If you want to know what your process uses from Windows (VM Size column in TaskManager) try:</p>\n\n<pre><code>Process.GetCurrentProcess().PrivateMemorySize64\n</code></pre>\n\n<p>If you want to know what your process has in RAM (as opposed to in the pagefile) (Mem Usage column in TaskManager) try:</p>\n\n<pre><code>Process.GetCurrentProcess().WorkingSet64\n</code></pre>\n\n<p>See <a href="http://web.archive.org/web/20051030010819/http://shsc.info/WindowsMemoryManagement" rel="noreferrer">here</a> for more explanation on the different sorts of memory.</p>\n'}, {'answer_id': 31182, 'author': 'OwenP', 'author_id': 2547, 'author_profile': 'https://Stackoverflow.com/users/2547', 'pm_score': 0, 'selected': False, 'text': "<p>Working set isn't a good property to use.  From what I gather, it includes everything the process can touch, even libraries shared by several processes, so you're seeing double-counted bytes in that counter.  Private memory is a much better counter to look at.</p>\n"}, {'answer_id': 31207, 'author': 'Daniel Magliola', 'author_id': 3314, 'author_profile': 'https://Stackoverflow.com/users/3314', 'pm_score': 3, 'selected': False, 'text': '<p>OK, I found through Google the same page that Lars mentioned, and I believe it\'s a great explanation for people that don\'t quite know how memory works (like me).</p>\n\n<p><a href="http://shsc.info/WindowsMemoryManagement" rel="noreferrer">http://shsc.info/WindowsMemoryManagement</a></p>\n\n<p>My short conclusion was:</p>\n\n<ul>\n<li><p>Private Bytes = The Memory my process has requested to store data. Some of it may be paged to disk or not. This is the information I was looking for.</p></li>\n<li><p>Virtual Bytes = The Private Bytes, plus the space shared with other processes for loaded DLLs, etc.</p></li>\n<li><p>Working Set = The portion of ALL the memory of my process that has not been paged to disk. So the amount paged to disk should be (Virtual - Working Set).</p></li>\n</ul>\n\n<p>Thanks all for your help!</p>\n'}, {'answer_id': 31231, 'author': 'Michał Piaskowski', 'author_id': 1534, 'author_profile': 'https://Stackoverflow.com/users/1534', 'pm_score': 0, 'selected': False, 'text': "<p>I'd suggest to also monitor how often pagefaults happen. A pagefault happens when you try to access some data that have been moved from physical memory to swap file and system has to read page from disk before you can access this data.</p>\n"}, {'answer_id': 289478, 'author': 'Michael Regan', 'author_id': 1027, 'author_profile': 'https://Stackoverflow.com/users/1027', 'pm_score': 3, 'selected': False, 'text': '<p>If you want to use the "Memory (Private Working Set)" as shown in Windows Vista task manager, which is the equivalent of Process Explorer "WS Private Bytes", here is the code. Probably best to throw this infinite loop in a thread/background task for real-time stats.</p>\n\n<pre><code>using System.Threading;\nusing System.Diagnostics;\n\n//namespace...class...method\n\nProcess thisProc = Process.GetCurrentProcess();\nPerformanceCounter PC = new PerformanceCounter();\n\nPC.CategoryName = "Process";\nPC.CounterName = "Working Set - Private";\nPC.InstanceName = thisProc.ProcessName;\n\nwhile (true)\n{\n String privMemory = (PC.NextValue()/1000).ToString()+"KB (Private Bytes)";\n //Do something with string privMemory\n\n Thread.Sleep(1000);\n}\n</code></pre>\n'}, {'answer_id': 9223644, 'author': 'Nicholas Petersen', 'author_id': 264031, 'author_profile': 'https://Stackoverflow.com/users/264031', 'pm_score': 2, 'selected': False, 'text': '<p>To get the value that Task Manager gives, my hat\'s off to Mike Regan\'s solution above. However, one change: it is not:  <code>perfCounter.NextValue()/1000;</code> but  <code>perfCounter.NextValue()/1024;</code> (i.e. a real kilobyte). This gives the exact value you see in Task Manager.</p>\n\n<p>Following is a full solution for displaying the \'memory usage\' (Task manager\'s, as given) in a simple way in your WPF or WinForms app (in this case, simply in the title). Just call this method within the new Window constructor:</p>\n\n<pre><code>    private void DisplayMemoryUsageInTitleAsync()\n    {\n        origWindowTitle = this.Title; // set WinForms or WPF Window Title to field\n        BackgroundWorker wrkr = new BackgroundWorker();\n        wrkr.WorkerReportsProgress = true;\n\n        wrkr.DoWork += (object sender, DoWorkEventArgs e) =&gt; {\n            Process currProcess = Process.GetCurrentProcess();\n            PerformanceCounter perfCntr = new PerformanceCounter();\n            perfCntr.CategoryName = "Process";\n            perfCntr.CounterName = "Working Set - Private";\n            perfCntr.InstanceName = currProcess.ProcessName;\n\n            while (true)\n            {\n                int value = (int)perfCntr.NextValue() / 1024;\n                string privateMemoryStr = value.ToString("n0") + "KB [Private Bytes]";\n                wrkr.ReportProgress(0, privateMemoryStr);\n                Thread.Sleep(1000);\n            }\n        };\n\n        wrkr.ProgressChanged += (object sender, ProgressChangedEventArgs e) =&gt; {\n            string val = e.UserState as string;\n            if (!string.IsNullOrEmpty(val))\n                this.Title = string.Format(@"{0}   ({1})", origWindowTitle, val);\n        };\n\n        wrkr.RunWorkerAsync();\n    }`\n</code></pre>\n'}, {'answer_id': 53290064, 'author': 'Phoeniceus Agelaius', 'author_id': 991566, 'author_profile': 'https://Stackoverflow.com/users/991566', 'pm_score': 2, 'selected': False, 'text': "<p>Is this a fair description? I'd like to share this with my team so please let me know if it is incorrect (or incomplete):</p>\n\n<p>There are several ways in C# to ask how much memory my process is using.</p>\n\n<ul>\n<li>Allocated memory can be managed (by the CLR) or unmanaged.</li>\n<li>Allocated memory can be virtual (stored on disk) or loaded (into RAM pages)</li>\n<li>Allocated memory can be private (used only by the process) or shared (e.g. belonging to a DLL that other processes are referencing).</li>\n</ul>\n\n<p>Given the above, here are some ways to measure memory usage in C#:</p>\n\n<p>1) Process.VirtualMemorySize64(): returns all the memory used by a process - managed or unmanaged, virtual or loaded, private or shared.</p>\n\n<p>2) Process.PrivateMemorySize64(): returns all the private memory used by a process - managed or unmanaged, virtual or loaded.</p>\n\n<p>3) Process.WorkingSet64(): returns all the private, loaded memory used by a process - managed or unmanaged</p>\n\n<p>4) GC.GetTotalMemory(): returns the amount of managed memory being watched by the garbage collector.</p>\n"}]
['https://Stackoverflow.com/questions/31096', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/3314/']