进程内存大小 - 不同的计数器
我想知道我自己的.Net服务器进程正在使用多少内存(用于监视和日志记录目的)。进程内存大小 - 不同的计数器
我使用:
Process.GetCurrentProcess().PrivateMemorySize64
然而,Process对象有几个不同的属性,让我读出所使用的存储空间: 分页,非分页缓冲,PagedSystem,NonPagedSystem,私人,虚拟,工作集
然后是“峰值”:我猜测它们只是存储了这些最后值得使用的最大值。
通读每个属性的MSDN定义对我来说并没有太大的帮助。我必须承认我关于如何管理内存的知识(就分页和虚拟而言)是非常有限的。
所以我的问题显然是“一个我应该使用哪一个?”,我也知道答案是“看情况”。
这个过程将基本保持一堆东西内存列出了发生的情况,而其他进程与其通信并查询它的东西。我期待的服务器将运行在这个需要大量内存的地方,所以随着时间的推移,我会查询这些数据,以便能够估计内存需求,并与内部列表的大小进行比较。
那么...我应该使用哪一个,为什么?
如果你想知道GC多少使用try:
GC.GetTotalMemory(true)
如果你想知道你的程序从Windows(在任务管理器VM大小列)使用try:
Process.GetCurrentProcess().PrivateMemorySize64
如果你想知道你的进程在RAM中有什么(而不是在页面文件中)(TaskManager中的Mem Usage列),请尝试:
Process.GetCurrentProcess().WorkingSet64
请参阅here以获取有关不同种类内存的更多说明。
工作集不是一个很好的使用属性。从我收集的信息中可以看出,它包含了该进程可以触及的所有内容,甚至是由多个进程共享的库,因此您可以在该计数器中看到重复计数的字节。私人内存是一个更好的计数器来看待。
OK,我通过谷歌发现,拉尔斯提到的同一页,我相信它是人们不太知道内存是如何工作的(像我一样),很好的解释。
http://shsc.info/WindowsMemoryManagement
我简短的结论是:
专用字节=我的进程已经请求来存储数据的内存。其中一些可能被分页到磁盘或不。这是我正在寻找的信息。
虚拟字节=专用字节,加上与其他进程用于加载的DLL等的空间共享
工作集=我的进程中所有未被分页到磁盘的内存部分。所以分页到磁盘的数量应该是(虚拟工作集)。
谢谢大家的帮忙!
我建议也要监视页面错误发生的频率。当您尝试访问一些已从物理内存移动到交换文件的数据时,页面错误会发生,系统必须从磁盘读取页面才能访问此数据。
如果您想使用Windows Vista任务管理器(与Process Explorer“WS Private Bytes”相同)中显示的“Memory(Private Working Set)”,则此处为代码。可能最好将这个无限循环放入线程/后台任务中以获取实时统计信息。
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应用程序(在本例中,仅在标题中)显示“内存使用情况”(任务管理器,如给出的)的完整解决方案。只需在新窗口构造函数中调用此方法:
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();
}`
这是我遇到的最准确的方法。我想匹配什么任务管理器显示。 – Andez 2012-10-30 21:10:22