2016-04-22 17 views
11

メモリを計算しようとしています。私はどのようにスタンバイ、ハードウェア予約済みの計算、およびWindowsのリソースモニタに示すように、メモリを変更することができます異なる種類のメモリを計算するアルゴリズム

ObjectQuery wql = new ObjectQuery("SELECT * FROM Win32_OperatingSystem"); 
      ManagementObjectSearcher searcher = new ManagementObjectSearcher(wql); 
      ManagementObjectCollection results = searcher.Get(); 

      //total amount of free physical memory in bytes 
      var Available = new ComputerInfo().AvailablePhysicalMemory; 
      //total amount of physical memory in bytes 
      var Total = new ComputerInfo().TotalPhysicalMemory; 

      var PhysicalMemoryInUse = Total - Available; 
      Object Free = new object(); 
      foreach (var result in results) 
      { 
       //Free amount 
       Free = result["FreePhysicalMemory"]; 
      } 
      var Cached = Total - PhysicalMemoryInUse - UInt64.Parse(Free.ToString()); 

を、使用中(InUse)、無料利用可能計算し、次のコードでキャッシュされていますか?

enter image description here

+2

「スタンバイメモリ」と「変更されたメモリ」とは何ですか? – quetzalcoatl

+0

@Scottあなたがリソースモニタから表示している値は、私が探している値です – nlstack01

+0

これはあなたのために働くかどうか分かりませんか? https://msdn.microsoft.com/en-us/library/windows/desktop/dn958303(v=vs.85).aspx –

答えて

7

ハードウェアは、物理的にインストールされたメモリの量と、OSによって報告された物理メモリの合計量との差です。

その他の情報は、パフォーマンスカウンターで取得できます。私は以下の例のクラスを持っていますが、これは堅牢な実装ではないことを知っています。適切なエラー処理とリソースのクリーンアップを追加する必要があります。ただし、このクラスのインスタンスをキャッシングし、必要に応じていつでもRefresh()で値を更新すると、かなりうまくいくはずです。

public sealed class MemoryInfo : IDisposable 
{ 
    [DllImport("kernel32.dll", SetLastError = true)] 
    [return: MarshalAs(UnmanagedType.Bool)] 
    private static extern bool GetPhysicallyInstalledSystemMemory(out ulong memoryInKilobytes); 

    private readonly PerformanceCounter availableCounter; 
    private readonly PerformanceCounter modifiedCounter; 
    private readonly PerformanceCounter freeCounter; 
    private readonly PerformanceCounter standbyCoreCounter; 
    private readonly PerformanceCounter standbyNormalCounter; 
    private readonly PerformanceCounter standbyReserveCounter; 

    private ulong osTotalMemory; 

    public ulong ModifiedBytes { get; private set; } 
    public ulong InUseBytes { get; private set; } 
    public ulong StandbyBytes { get; private set; } 
    public ulong FreeBytes { get; private set; } 
    public ulong HardwareReserved { get; } 

    public MemoryInfo() 
    { 
     var computerInfo = new ComputerInfo(); 

     osTotalMemory = computerInfo.TotalPhysicalMemory; 

     ulong installedPhysicalMemInKb; 
     GetPhysicallyInstalledSystemMemory(out installedPhysicalMemInKb); 

     this.HardwareReserved = installedPhysicalMemInKb * 1024 - osTotalMemory; 

     modifiedCounter = new PerformanceCounter("Memory", "Modified Page List Bytes"); 
     standbyCoreCounter = new PerformanceCounter("Memory", "Standby Cache Core Bytes"); 
     standbyNormalCounter = new PerformanceCounter("Memory", "Standby Cache Normal Priority Bytes"); 
     standbyReserveCounter = new PerformanceCounter("Memory", "Standby Cache Reserve Bytes"); 
     freeCounter = new PerformanceCounter("Memory", "Free & Zero Page List Bytes"); 
     availableCounter = new PerformanceCounter("Memory", "Available Bytes"); 

     Refresh(); 
    } 

    public void Refresh() 
    { 
     ModifiedBytes = (ulong)modifiedCounter.NextSample().RawValue; 
     StandbyBytes = (ulong)standbyCoreCounter.NextSample().RawValue + 
         (ulong)standbyNormalCounter.NextSample().RawValue + 
         (ulong)standbyReserveCounter.NextSample().RawValue; 
     FreeBytes = (ulong)freeCounter.NextSample().RawValue; 
     InUseBytes = osTotalMemory - (ulong) availableCounter.NextSample().RawValue; 

    } 

    public void Dispose() 
    { 
     modifiedCounter.Dispose(); 
     standbyCoreCounter.Dispose(); 
     standbyNormalCounter.Dispose(); 
     standbyReserveCounter.Dispose(); 
     freeCounter.Dispose(); 
    } 
} 

はPERFカウンターが一緒にグループ化されていないように、このようにそれをやっての欠点がありますので、あなたは、特定の時点でシステムメモリの「本当の」スナップショットを得ることはありません。おそらく、PInvokeを使用してPdh* win32 api関数を直接使用するように改善することができます。

また、WMI(データはWin32_PerfRawData_PerfOS_Memory)を使用するように変更することもできますが、どのように実行するのか分かりません。

0

何を後にしていることは、ここにあるかどうかを確認してください - コンソールアプリケーションを作成し、Program.csの内容の上にこれを貼り付けます。コマンドラインから>を実行し、関連するメモリカウンタを探します。

using System; 
using System.Diagnostics; 

namespace ConsoleApplication2 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      var categories = PerformanceCounterCategory.GetCategories(); 

      foreach (var cat in categories) 
      { 
       if (cat.CategoryType != PerformanceCounterCategoryType.MultiInstance) 
       { 
        Console.WriteLine("Category: " + cat.CategoryName); 
        foreach (var counter in cat.GetCounters()) 
        { 
         Console.WriteLine("Counter: " + counter.CounterName + ": " + counter.NextSample().RawValue); 
        } 
       } 
       else //if (cat.CategoryType == PerformanceCounterCategoryType.MultiInstance) 
       { 
        foreach (var instance in cat.GetInstanceNames()) 
        { 
         Console.WriteLine("Instance: " + instance); 
         foreach (var counter in cat.GetCounters(instance)) 
         { 
          try 
          { 
           Console.WriteLine("Counter: " + counter.CounterName + ": " + counter.NextSample().RawValue); 
          } catch 
          { 
           // swallow exceptions for counter that require a set base. 
          } 
         } 
        } 
       } 
      } 

      Console.ReadLine();   
     }  
    } 
} 
+0

Counter:Modified Page List Bytes:62291968とCounter:スタンバイキャッシュ通常の優先度バイトは、それらが確かではないかもしれませんか?それは理にかなっていますか?ハードウェアが予約されていないことを確認してください – nlstack01

+0

これらの値が正しい場合は、どのような方法でそれらにアクセスするのが最も速いのですか?このコードは実行に時間がかかります – nlstack01

0

私はChristopherのサンプルを使用し、ハードウェア予約を取得するためにすべてのWMIに拡張しました。

using System; 
using System.Management; 

namespace ConsoleApplication2 
{ 
    class Program 
    { 

     static void Main(string[] args) 
     { 
      try 
      { 
       ManagementScope Scope; 
       Scope = new ManagementScope(String.Format("\\\\{0}\\root\\CIMV2", "."), null); 
       Scope.Connect(); 

       double totalVisibleMemory = 0; 

       ObjectQuery wql = new ObjectQuery("SELECT * FROM Win32_OperatingSystem"); 
       ManagementObjectSearcher searcher = new ManagementObjectSearcher(wql); 
       ManagementObjectCollection results = searcher.Get(); 

       foreach (ManagementObject result in results) 
       { 
        totalVisibleMemory = double.Parse(result["TotalVisibleMemorySize"].ToString())/1024; 
        Console.WriteLine("Total Visible Memory: {0:0} mb", totalVisibleMemory); 
        Console.WriteLine("Free Physical Memory: {0:0} mb", double.Parse(result["FreePhysicalMemory"].ToString())/1024); 
        Console.WriteLine("Total Virtual Memory: {0:0} mb", double.Parse(result["TotalVirtualMemorySize"].ToString())/1024); 
        Console.WriteLine("Free Virtual Memory: {0:0} mb", double.Parse(result["FreeVirtualMemory"].ToString())/1024); 
       } 

       ObjectQuery Query = new ObjectQuery("SELECT Capacity FROM Win32_PhysicalMemory"); 
       ManagementObjectSearcher Searcher = new ManagementObjectSearcher(Scope, Query); 
       UInt64 Capacity = 0; 
       foreach (ManagementObject WmiObject in Searcher.Get()) 
       { 
        Capacity += (UInt64)WmiObject["Capacity"]; 
       } 

       var totalPhysicalMemory = Capacity/(1024 * 1024); 
       Console.WriteLine(String.Format("Total Physical Memory {0:0} mb", Capacity/(1024 * 1024))); 
       var hardwareReserved = totalPhysicalMemory - totalVisibleMemory; 

        Console.WriteLine(string.Format("Hardware Reserved Memory {0:0} mb", hardwareReserved)); 
      } 
      catch (Exception e) 
      { 
       Console.WriteLine(string.Format("Exception {0} Trace {1}", e.Message, e.StackTrace)); 
      } 
      Console.WriteLine("Press Enter to exit"); 
      Console.Read(); 
     } 
    } 
} 
関連する問題