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

发布于 2024-07-04 00:51:03 字数 575 浏览 7 评论 0原文

我试图找出我自己的 .Net 服务器进程使用了​​多少内存(用于监视和日志记录目的)。

我正在使用:

Process.GetCurrentProcess().PrivateMemorySize64

但是,Process 对象有几个不同的属性,可以让我读取所使用的内存空间: Paged、NonPaged、PagedSystem、NonPagedSystem、Private、Virtual、WorkingSet

,然后是“峰值”:我猜它只是存储这些最后一个所取的最大值。

通读 MSDN 对每个属性的定义并没有证明对我有太大帮助。 我必须承认我关于如何管理内存(就分页和虚拟而言)的知识非常有限。

所以我的问题显然是“我应该使用哪一个?”,我知道答案是“这取决于”。

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

那么...我应该使用哪一个,为什么?

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

I'm using:

Process.GetCurrentProcess().PrivateMemorySize64

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

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

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.

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

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.

So... Which one should I use and why?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

凡尘雨 2024-07-11 00:51:03

好的,我通过 Google 找到了 Lars 提到的同一页面,我相信对于那些不太了解记忆如何工作的人(比如我)来说这是一个很好的解释。

http://shsc.info/WindowsMemoryManagement

我的简短结论是:

  • 私有字节 = 我的进程拥有的内存请求存储数据。 其中一些可能会分页到磁盘,也可能不会。 这是我正在寻找的信息。

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

    虚拟字节

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

感谢你的帮助!

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).

http://shsc.info/WindowsMemoryManagement

My short conclusion was:

  • 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.

  • Virtual Bytes = The Private Bytes, plus the space shared with other processes for loaded DLLs, etc.

  • 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).

Thanks all for your help!

初相遇 2024-07-11 00:51:03

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

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.

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);
}
乖乖公主 2024-07-11 00:51:03

为了获得任务管理器提供的价值,我向 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();
    }`

To get the value that Task Manager gives, my hat's off to Mike Regan's solution above. However, one change: it is not: perfCounter.NextValue()/1000; but perfCounter.NextValue()/1024; (i.e. a real kilobyte). This gives the exact value you see in Task Manager.

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:

    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();
    }`
痴情换悲伤 2024-07-11 00:51:03

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

GC.GetTotalMemory(true)

如果你想知道你的进程在 Windows 中使用了什么(TaskManager 中的 VM Size 列),请尝试:

Process.GetCurrentProcess().PrivateMemorySize64

如果你想知道你的进程在 RAM 中拥有什么(而不是在页面文件中) )(TaskManager 中的内存使用列)尝试:

Process.GetCurrentProcess().WorkingSet64

请参阅此处 有关不同类型内存的更多说明。

If you want to know how much the GC uses try:

GC.GetTotalMemory(true)

If you want to know what your process uses from Windows (VM Size column in TaskManager) try:

Process.GetCurrentProcess().PrivateMemorySize64

If you want to know what your process has in RAM (as opposed to in the pagefile) (Mem Usage column in TaskManager) try:

Process.GetCurrentProcess().WorkingSet64

See here for more explanation on the different sorts of memory.

萌吟 2024-07-11 00:51:03

工作集不是一个很好使用的属性。 根据我收集的信息,它包括进程可以接触的所有内容,甚至是多个进程共享的库,因此您会在该计数器中看到重复计算的字节。 私有内存是一个更好看的计数器。

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.

何以笙箫默 2024-07-11 00:51:03

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

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.

往日 2024-07-11 00:51:03

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

C# 中有多种方法可以询问我的进程使用了​​多少内存。

  • 分配的内存可以是托管的(由 CLR)或非托管的。
  • 分配的内存可以是虚拟的(存储在磁盘上)或加载的(加载到 RAM 页中)。
  • 分配的内存可以是私有的(仅由进程使用)或共享的(例如属于其他进程正在引用的 DLL)。

鉴于上述情况,以下是测量 C# 中内存使用情况的一些方法:

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

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

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

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

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):

There are several ways in C# to ask how much memory my process is using.

  • Allocated memory can be managed (by the CLR) or unmanaged.
  • Allocated memory can be virtual (stored on disk) or loaded (into RAM pages)
  • Allocated memory can be private (used only by the process) or shared (e.g. belonging to a DLL that other processes are referencing).

Given the above, here are some ways to measure memory usage in C#:

1) Process.VirtualMemorySize64(): returns all the memory used by a process - managed or unmanaged, virtual or loaded, private or shared.

2) Process.PrivateMemorySize64(): returns all the private memory used by a process - managed or unmanaged, virtual or loaded.

3) Process.WorkingSet64(): returns all the private, loaded memory used by a process - managed or unmanaged

4) GC.GetTotalMemory(): returns the amount of managed memory being watched by the garbage collector.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文