Подтвердить что ты не робот

С# Использовать память в%

Я создал PerformanceCounter, который может проверить общее использование памяти в%, но проблема в том, что она не дает мне того же значения, что и в диспетчере задач показывает мне. например: моя программа говорит 34%, но диспетчер задач говорит 40%.

Любые идеи?

Примечание
Я пытаюсь получить доступную ОЗУ системы, а не используемую ОЗУ процессом.

Текущий код

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) + "%";

ИЗМЕНИТЬ
Я обновляю индикатор прогресса и метку каждую секунду таймером.

4b9b3361

Ответ 1

Вы можете использовать API окон GetPerformanceInfo, он показывает точно такие же значения, как Windows Task Manager в Windows 7, вот консольное приложение, которое получает доступную физическую память, вы можете легко получить другую информацию, возвращаемую 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;
      }

    }
  }
}

Ответ 2

Я думаю, что процент физической памяти, указанный диспетчером задач, на самом деле представляет собой другую метрику для % Committed Bytes In Use, которую использует ваш PerformanceCounter.

На моей машине существует явная разница в 20% между этими значениями при просмотре на мониторе производительности:

enter image description here

В этой статье указано, что метка% Committed Bytes учитывает размер файла подкачки, а не только физическую память компьютера. Это объясняет, почему это значение постоянно ниже, чем значение Task Manager.

Возможно, вам удастся подсчитать процент, используя метку Memory \ Available Bytes, но я не уверен, как получить общий объем физической памяти от PerformanceCounter.

Ответ 3

Счетчики производительности - это не очень хорошая идея. Используйте этот код, чтобы получить% использования памяти из диспетчера задач

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;
}

Ответ 4

Вы можете использовать "show description" в нижней части монитора производительности. Процитировать

% Committed Bytes In Use - отношение памяти \Committed Bytes к пределу памяти \Commit Limit. Обозначенная память - это физическая память в использование, для которого пространство зарезервировано в файле подкачки, если оно необходимо записать на диск. Предел фиксации определяется размером файла подкачки. Если файл подкачки увеличен, предел фиксации увеличивается, и отношение уменьшается). Этот счетчик отображает текущее процентное значение; это не среднее.

Soo yes PM использует файл подкачки, в то время как TM использует реальную ОЗУ.