C#以%为单位获取已用内存

Yuk*_*uya 41 c# performancecounter

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

有任何想法吗?

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

现行守则

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) + "%";
Run Code Online (Sandbox Code Playgroud)

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

Ant*_*ula 53

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

更新:我更新了这段代码以显示百分比,它不是最佳的,因为它调用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;
      }

    }
  }
}
Run Code Online (Sandbox Code Playgroud)

  • 我把小班放在一起,现在更容易使用,这里是http://www.antoniob.com/windows-psapi-getperformanceinfo-csharp-wrapper.html (2认同)

rav*_*ned 8

我认为任务管理器报告的物理内存百分比实际上与% Committed Bytes In UsePerformanceCounter使用的度量标准不同.

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

在此输入图像描述

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

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


ZOX*_*IVO 7

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

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;
}
Run Code Online (Sandbox Code Playgroud)

  • 您能解释一下为什么性能计数器不是一个好主意吗? (4认同)