[英]Process Memory Size - Different Counters
我試圖找出我自己的.Net服務器進程正在使用多少內存(用於監視和記錄目的)。
我正在使用:
Process.GetCurrentProcess().PrivateMemorySize64
但是,Process對象有幾個不同的屬性,讓我可以讀取使用的內存空間:Paged,NonPaged,PagedSystem,NonPagedSystem,Private,Virtual,WorkingSet
然后是“峰值”:我猜測它只存儲了最后一次所用的最大值。
閱讀每個屬性的MSDN定義對我來說並沒有太大幫助。 我不得不承認我對內存管理方式的了解(就分頁和虛擬內容而言)非常有限。
所以我的問題顯然是“我應該使用哪一個?”,我知道答案是“它取決於”。
這個過程基本上會在內存中保存一堆列表,而其他進程與之通信並查詢它。 我期望運行它的服務器需要大量的RAM,因此我會隨着時間的推移查詢這些數據,以便能夠估計RAM要求與其保留的列表大小相比較。
那么......我應該使用哪一個?為什么?
如果您想知道GC使用了多少嘗試:
GC.GetTotalMemory(true)
如果您想知道您的進程從Windows使用的內容(TaskManager中的VM Size列),請嘗試:
Process.GetCurrentProcess().PrivateMemorySize64
如果你想知道你的進程在RAM中的位置(而不是在頁面文件中)(TaskManager中的Mem Usage列),請嘗試:
Process.GetCurrentProcess().WorkingSet64
有關不同類型的內存的更多說明,請參見此處 。
好吧,我通過Google找到了Lars提到的同一頁面,我相信這對於那些不太了解記憶效果的人來說是一個很好的解釋(就像我一樣)。
http://shsc.info/WindowsMemoryManagement
我的簡短結論是:
Private Bytes =我的進程請求存儲數據的內存。 其中一些可能會被分頁到磁盤。 這是我正在尋找的信息。
虛擬字節數=私有字節數,加上與加載的DLL等的其他進程共享的空間。
Working Set =我的進程的所有內存中未被分頁到磁盤的部分。 所以分頁到磁盤的數量應該是(虛擬 - 工作集)。
感謝你的幫助!
如果要使用Windows Vista任務管理器中顯示的“內存(專用工作集)”,它等同於Process Explorer“WS Private Bytes”,則代碼如下所示。 可能最好將這個無限循環拋在一個線程/后台任務中,用於實時統計。
using System.Threading;
using System.Diagnostics;
//namespace...class...method
Process thisProc = Process.GetCurrentProcess();
PerformanceCounter PC = new PerformanceCounter();
PC.CategoryName = "Process";
PC.CounterName = "Working Set - Private";
PC.InstanceName = thisProc.ProcessName;
while (true)
{
String privMemory = (PC.NextValue()/1000).ToString()+"KB (Private Bytes)";
//Do something with string privMemory
Thread.Sleep(1000);
}
為了獲得任務管理器給出的價值,我的帽子將由Mike Regan的解決方案提供。 但是,一個改變:它不是: perfCounter.NextValue()/1000;
但是perfCounter.NextValue()/1024;
(即一個真正的千字節)。 這給出了您在任務管理器中看到的確切值。
以下是在WPF或WinForms應用程序中以簡單方式顯示“內存使用”(任務管理器,如給定)的完整解決方案(在本例中,僅在標題中)。 只需在新的Window構造函數中調用此方法:
private void DisplayMemoryUsageInTitleAsync()
{
origWindowTitle = this.Title; // set WinForms or WPF Window Title to field
BackgroundWorker wrkr = new BackgroundWorker();
wrkr.WorkerReportsProgress = true;
wrkr.DoWork += (object sender, DoWorkEventArgs e) => {
Process currProcess = Process.GetCurrentProcess();
PerformanceCounter perfCntr = new PerformanceCounter();
perfCntr.CategoryName = "Process";
perfCntr.CounterName = "Working Set - Private";
perfCntr.InstanceName = currProcess.ProcessName;
while (true)
{
int value = (int)perfCntr.NextValue() / 1024;
string privateMemoryStr = value.ToString("n0") + "KB [Private Bytes]";
wrkr.ReportProgress(0, privateMemoryStr);
Thread.Sleep(1000);
}
};
wrkr.ProgressChanged += (object sender, ProgressChangedEventArgs e) => {
string val = e.UserState as string;
if (!string.IsNullOrEmpty(val))
this.Title = string.Format(@"{0} ({1})", origWindowTitle, val);
};
wrkr.RunWorkerAsync();
}`
工作集不是一個好用的屬性。 從我收集的內容中,它包括進程可以觸及的所有內容,甚至是由多個進程共享的庫,因此您在該計數器中看到了雙重計數的字節。 私人記憶是一個更好的反擊。
我建議還要監控頁面故障發生的頻率。 當您嘗試訪問已從物理內存移動到交換文件的某些數據時,會發生頁面故障,並且系統必須先從磁盤讀取頁面,然后才能訪問此數據。
這是一個公平的描述嗎? 我想與我的團隊分享這個,所以如果不正確(或不完整),請告訴我:
C#有幾種方法可以詢問我的進程使用了多少內存。
鑒於上述情況,以下是一些測量C#內存使用情況的方法:
1)Process.VirtualMemorySize64():返回進程使用的所有內存 - 托管或非托管,虛擬或加載,私有或共享。
2)Process.PrivateMemorySize64():返回進程使用的所有私有內存 - 托管或非托管,虛擬或加載。
3)Process.WorkingSet64():返回進程使用的所有私有,已加載的內存 - 托管或非托管
4)GC.GetTotalMemory():返回垃圾收集器正在監視的托管內存量。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.