Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 进程内存大小-不同的计数器_C#_.net_Memory_Process_Diagnostics - Fatal编程技术网

C# 进程内存大小-不同的计数器

C# 进程内存大小-不同的计数器,c#,.net,memory,process,diagnostics,C#,.net,Memory,Process,Diagnostics,我试图找出我自己的.Net服务器进程正在使用多少内存(用于监视和记录) 我正在使用: Process.GetCurrentProcess().PrivateMemorySize64 但是,Process对象有几个不同的属性,让我可以读取使用的内存空间: 分页、非分页、分页系统、非分页系统、专用、虚拟、工作集 然后是“峰值”:我猜它只存储了最后一个峰值的最大值 阅读每个属性的MSDN定义对我来说并没有太大帮助。我必须承认,我对如何管理内存(就分页和虚拟运行而言)的了解非常有限 因此,我的问题显然

我试图找出我自己的.Net服务器进程正在使用多少内存(用于监视和记录)

我正在使用:

Process.GetCurrentProcess().PrivateMemorySize64
但是,Process对象有几个不同的属性,让我可以读取使用的内存空间: 分页、非分页、分页系统、非分页系统、专用、虚拟、工作集

然后是“峰值”:我猜它只存储了最后一个峰值的最大值

阅读每个属性的MSDN定义对我来说并没有太大帮助。我必须承认,我对如何管理内存(就分页和虚拟运行而言)的了解非常有限

因此,我的问题显然是“我应该使用哪一个?”,我知道答案是“视情况而定”

这个过程基本上会在内存中保存一组正在进行的事情的列表,而其他过程会与之通信并查询这些事情。我希望运行此功能的服务器需要大量的RAM,因此我会随着时间的推移查询这些数据,以便能够在与它保存的列表的大小进行比较时估计RAM需求


所以。。。我应该使用哪一个?为什么?

如果您想知道GC使用了多少,请尝试:

GC.GetTotalMemory(true)
如果您想知道进程在Windows中使用了什么(TaskManager中的VM大小列),请尝试:

如果您想知道您的进程在RAM(而不是页面文件)中有什么内容(TaskManager中的Mem Usage列),请尝试:


有关不同类型内存的详细说明,请参阅。

工作集不是一个好的属性。从我收集的信息来看,它包括进程可以触及的所有内容,甚至包括由多个进程共享的库,因此在计数器中可以看到重复计数的字节。私有内存是一个更好的计数器。

好吧,我在谷歌上找到了Lars提到的同一个页面,我相信这对那些不太了解内存如何工作的人(比如我)来说是一个很好的解释

我的简短结论是:

  • Private Bytes=进程请求存储数据的内存。其中一些可能被分页到磁盘或不被分页到磁盘。这就是我要找的信息

  • 虚拟字节=专用字节,加上与加载DLL的其他进程共享的空间,等等

  • 工作集=进程中所有内存中尚未分页到磁盘的部分。因此,分页到磁盘的数量应该是(虚拟工作集)


谢谢大家的帮助

我建议还应该监控页面错误发生的频率。当您试图访问从物理内存移动到交换文件的某些数据时,会发生页面错误,系统必须先从磁盘读取页面,然后才能访问此数据。

如果您想使用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);
}

为了获得Task Manager所提供的价值,我要感谢上面Mike Regan的解决方案。但是,有一个变化:它不是:
perfCounter.NextValue()/1000
but
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();
    }`

这是一个公平的描述吗?我想与我的团队分享这一点,因此如果不正确(或不完整),请告知我:

在C#中有几种方法可以询问进程使用了多少内存

  • 分配的内存可以是(由CLR)管理的,也可以是非托管的
  • 分配的内存可以是虚拟的(存储在磁盘上)或加载的(到RAM页中)
  • 分配的内存可以是私有的(仅由进程使用)或共享的(例如,属于其他进程引用的DLL)
鉴于上述情况,以下是一些测量C#中内存使用情况的方法:

1) Process.VirtualMemorySize64():返回进程使用的所有内存-托管或非托管、虚拟或加载、私有或共享

2) Process.PrivateMemorySize64():返回进程使用的所有私有内存-托管或非托管、虚拟或加载

3) Process.WorkingSet64():返回进程托管或非托管使用的所有私有加载内存


4) GC.GetTotalMemory():返回垃圾收集器监视的托管内存量。

这是我遇到的最准确的一个。我想匹配任务管理器显示的内容。链接已断开..:(看起来没有一个显示TaskManager或VS Diagnostics的内存
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);
}
    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();
    }`