web-dev-qa-db-fra.com

C # Obtenir la mémoire utilisée en%

J'ai créé un compteur de performances qui peut vérifier l'utilisation totale de la mémoire en%, mais le problème est qu'il ne me donne pas la même valeur que celle que me montre le gestionnaire de tâches. par exemple: mon programme dit 34% mais le chef de projet dit 40%.

Des idées?

REMARQUE
J'essaie d'obtenir la RAM disponible du système, et non le RAM utilisé par un processus.

Code actuel

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

MODIFIER
J'actualise la barre de progression et l'étiquette toutes les secondes avec une minuterie.

37
Yuki Kutsuya

Vous pouvez utiliser l’API Windows GetPerformanceInfo, elle affiche exactement les mêmes valeurs que le Gestionnaire de tâches Windows sous Windows 7. Voici l’application console qui récupère la mémoire physique disponible. Vous pouvez facilement obtenir d’autres informations renvoyées par GetPerformanceInfo, consultez MSDN PERFORMANCE_INFORMATION structure documentation pour savoir comment calculer la valeur dans MiB, en principe toutes les valeurs SIZE_T sont dans des pages, vous devez donc la multiplier avec PageSize.

Mise à jour: j'ai mis à jour ce code pour afficher le pourcentage, ce n'est pas optimal car il appelle GetPerformanceInfo à deux reprises, mais j'espère que vous avez compris.

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

    }
  }
}
51
Antonio Bakula

Je pense que le pourcentage de mémoire physique signalé par le Gestionnaire des tâches est en réalité une mesure différente de celle de % Committed Bytes In Use utilisé par votre PerformanceCounter.

Sur ma machine, il existe une nette différence de 20% entre ces valeurs lorsque visualisées dans le moniteur de performances:

enter image description here

Cet article indique que la mesure% d'octets engagés prend en compte la taille du fichier d'échange, pas seulement la mémoire physique de la machine. Cela expliquerait pourquoi cette valeur est systématiquement inférieure à la valeur du Gestionnaire des tâches.

Vous aurez peut-être plus de chance en calculant un pourcentage en utilisant la métrique Memory \ Available Bytes, mais je ne sais pas comment obtenir la quantité totale de mémoire physique de PerformanceCounter.

8
raveturned

Les compteurs de performance ne sont pas une bonne idée . Utilisez ce code pour obtenir% de l'utilisation de la mémoire à partir du Gestionnaire des tâches.

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

Vous pouvez utiliser "show description" au bas de l'Analyseur de performances. Citer

% D'octets validés utilisés correspond au rapport entre mémoire\octets validés et mémoire\limite de validation. La mémoire dédiée est la mémoire physique en utiliser pour lequel un espace a été réservé dans le fichier d'échange, le cas échéant besoin d'être écrit sur le disque. La limite de validation est déterminée par la taille du fichier de pagination. Si le fichier d'échange est agrandi, la limite de validation augmente et le rapport est réduit). Ce compteur affiche le valeur actuelle en pourcentage seulement; ce n'est pas une moyenne.

Soo yes PM utilise le fichier d'échange, alors que TM utilise la mémoire vive réelle.

0
KLAVDIJ LAPAJNE