C# 获取已用内存百分比

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10027341/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 12:11:08  来源:igfitidea点击:

C# Get used memory in %

c#performancecounter

提问by Yuki Kutsuya

I've created a performancecounter that can check the total memory usage in %, but the problem is that it doesn't give me the same value as in task manager shows me. for example: my program says 34% but task manager says 40%.

我创建了一个性能计数器,可以检查以 % 为单位的总内存使用情况,但问题是它没有给我与任务管理器中显示的值相同的值。例如:我的程序说 34% 但任务管理器说 40%。

Any ideas?

有任何想法吗?

NOTE
I try to get the available RAM of the system, not the used RAM by a process.

注意
我尝试获取系统的可用 RAM,而不是进程使用的 RAM。

Current Code

当前代码

private PerformanceCounter performanceCounterRAM = new PerformanceCounter();

performanceCounterRAM.CounterName = "% Committed Bytes In Use";
performanceCounterRAM.CategoryName = "Memory";

progressBarRAM.Value = (int)(performanceCounterRAM.NextValue());
            labelRAM.Text = "RAM: " + progressBarRAM.Value.ToString(CultureInfo.InvariantCulture) + "%";

EDIT
I refresh the progressbar and the label every second with a timer.

编辑
我用计时器每秒刷新进度条和标签。

采纳答案by Antonio Bakula

You could use GetPerformanceInfo windows API, it shows exactly the same values as Windows Task Manager on Windows 7, here is the console application that get's available physical memory, you could easily get other information that GetPerformanceInfo returns, consult MSDN PERFORMANCE_INFORMATIONstructure documentation to see how to calculate value in MiB, basically all SIZE_T values are in pages, so you must multiply it with PageSize.

您可以使用 GetPerformanceInfo windows API,它显示的值与 Windows 7 上的 Windows 任务管理器完全相同,这是获取可用物理内存的控制台应用程序,您可以轻松获取 GetPerformanceInfo 返回的其他信息,请参阅 MSDN PERFORMANCE_INFORMATION结构文档以了解如何要以 MiB 为单位计算值,基本上所有 SIZE_T 值都以页为单位,因此您必须将其与 PageSize 相乘。

Update: I updated this code to show percentage, it's not optimal because it's calling GetPerformanceInfo two times, but I hope that you get the idea.

更新:我更新了这段代码以显示百分比,它不是最佳的,因为它调用了两次 GetPerformanceInfo,但我希望你能明白。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;

namespace ConsoleApplicationPlayground
{
  class Program
  {
    static void Main(string[] args)
    {
      while (true)
      {
        Int64 phav = PerformanceInfo.GetPhysicalAvailableMemoryInMiB();
        Int64 tot = PerformanceInfo.GetTotalMemoryInMiB();
        decimal percentFree = ((decimal)phav / (decimal)tot) * 100;
        decimal percentOccupied = 100 - percentFree;
        Console.WriteLine("Available Physical Memory (MiB) " + phav.ToString());
        Console.WriteLine("Total Memory (MiB) " + tot.ToString());
        Console.WriteLine("Free (%) " + percentFree.ToString());
        Console.WriteLine("Occupied (%) " + percentOccupied.ToString());
        Console.ReadLine();
      }
    }
  }

  public static class PerformanceInfo
  {
    [DllImport("psapi.dll", SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool GetPerformanceInfo([Out] out PerformanceInformation PerformanceInformation, [In] int Size);

    [StructLayout(LayoutKind.Sequential)]
    public struct PerformanceInformation
    {
      public int Size;
      public IntPtr CommitTotal;
      public IntPtr CommitLimit;
      public IntPtr CommitPeak;
      public IntPtr PhysicalTotal;
      public IntPtr PhysicalAvailable;
      public IntPtr SystemCache;
      public IntPtr KernelTotal;
      public IntPtr KernelPaged;
      public IntPtr KernelNonPaged;
      public IntPtr PageSize;
      public int HandlesCount;
      public int ProcessCount;
      public int ThreadCount;
    }

    public static Int64 GetPhysicalAvailableMemoryInMiB()
    {
        PerformanceInformation pi = new PerformanceInformation();
        if (GetPerformanceInfo(out pi, Marshal.SizeOf(pi)))
        {
          return Convert.ToInt64((pi.PhysicalAvailable.ToInt64() * pi.PageSize.ToInt64() / 1048576));
        }
        else
        {
          return -1;
        }

    }

    public static Int64 GetTotalMemoryInMiB()
    {
      PerformanceInformation pi = new PerformanceInformation();
      if (GetPerformanceInfo(out pi, Marshal.SizeOf(pi)))
      {
        return Convert.ToInt64((pi.PhysicalTotal.ToInt64() * pi.PageSize.ToInt64() / 1048576));
      }
      else
      {
        return -1;
      }

    }
  }
}

回答by raveturned

I think the Physical memory percentage reported by Task Manager is actually a different metric to the % Committed Bytes In Useyour PerformanceCounter is using.

我认为任务管理器报告的物理内存百分比实际上与% Committed Bytes In Use您的 PerformanceCounter 使用的指标不同。

On my machine there's a clear 20% difference between these values when viewed in the performance monitor:

在我的机器上,在性能监视器中查看时,这些值之间存在明显的 20% 差异:

enter image description here

在此处输入图片说明

This articleindicates that the % Committed Bytes metric takes the size of the pagefile into account, not just the machine's physical memory. This would explain why this value is consistently lower than Task Manager's value.

本文指出 % Committed Bytes 指标考虑了页面文件的大小,而不仅仅是机器的物理内存。这将解释为什么此值始终低于任务管理器的值。

You may have better luck calculating a percentage using the Memory \ Available Bytesmetric, but I'm not sure how to get the total amount of physical memory from PerformanceCounter.

使用该Memory \ Available Bytes指标计算百分比可能会更好,但我不确定如何从 PerformanceCounter 获取物理内存总量。

回答by KLAVDIJ LAPAJNE

You can use "show description" on the bottom of Performance monitor. To quote

您可以使用性能监视器底部的“显示说明”。报价

% Committed Bytes In Use is the ratio of Memory\Committed Bytes to the Memory\Commit Limit. Committed memory is the physical memory in use for which space has been reserved in the paging file should it need to be written to disk. The commit limit is determined by the size of the paging file. If the paging file is enlarged, the commit limit increases, and the ratio is reduced). This counter displays the current percentage value only; it is not an average.

% Committed Bytes In Use 是 Memory\Committed Bytes 与 Memory\Commit Limit 的比率。提交的内存是正在使用的物理内存,如果需要将其写入磁盘,则页面文件中已为其保留空间。提交限制由分页文件的大小决定。如果分页文件扩大,提交限制增加,比例减少)。此计数器仅显示当前百分比值;这不是平均值。

Soo yes PM uses the paging file, while TM uses actual RAM.

Soo yes PM 使用分页文件,而 TM 使用实际 RAM。

回答by ZOXEXIVO

Performance counters is not good idea. Use this code to get % of memory usage from Task Manager

性能计数器不是一个好主意。使用此代码从任务管理器获取内存使用百分比

var wmiObject = new ManagementObjectSearcher("select * from Win32_OperatingSystem");

var memoryValues = wmiObject.Get().Cast<ManagementObject>().Select(mo => new {
    FreePhysicalMemory = Double.Parse(mo["FreePhysicalMemory"].ToString()),
    TotalVisibleMemorySize = Double.Parse(mo["TotalVisibleMemorySize"].ToString())
}).FirstOrDefault();

if (memoryValues != null) {
    var percent = ((memoryValues.TotalVisibleMemorySize - memoryValues.FreePhysicalMemory) / memoryValues.TotalVisibleMemorySize) * 100;
}