你如何获得计算机的RAM总量?

Joe*_*oel 78 c# memory performancecounter

使用C#,我想获得我的计算机拥有的RAM总量.使用PerformanceCounter,我可以通过设置获得可用ram的数量:

counter.CategoryName = "Memory";
counter.Countername = "Available MBytes";
Run Code Online (Sandbox Code Playgroud)

但我似乎无法找到获得总内存量的方法.我该怎么做呢?

更新:

MagicKat:我在搜索时看到了它,但它不起作用 - "你错过了一个装配或参考吗?".我希望将它添加到参考文献中,但我没有在那里看到它.

Mag*_*Kat 174

添加对Microsoft.VisualBasic和的引用using Microsoft.VisualBasic.Devices;.

ComputerInfo课程包含您需要的所有信息.

  • +1:有些人厌恶从C#引用Microsoft.VisualBasic命名空间,尽管它实际上只是作为其他一部分安装的另一个程序集. (52认同)
  • 为什么这个被投了票呢?投票回来了!这是最简单的方法,是的,你可以从C#中做到这一点. (10认同)
  • 对于任何对使用(新的ComputerInfo()).TotalPhysicalMemory的怀疑,它在具有更多内存的系统上工作正常.它的返回类型是无符号长整数,因此如果没有(无效)强制转换,则无法使用负数. (6认同)
  • var totalGBRam = Convert.ToInt32((new ComputerInfo().TotalPhysicalMemory / (Math.Pow(1024, 3))) + 0.5); (4认同)
  • 在带有 8gb 内存的 Windows7 64 位上返回负垃圾值。这就是你被否决的原因? (2认同)

Phi*_*eck 59

p/invoke方式编辑:更改为GlobalMemoryStatusEx以提供准确的结果(呵呵)

  [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
  private class MEMORYSTATUSEX
  {
     public uint dwLength;
     public uint dwMemoryLoad;
     public ulong ullTotalPhys;
     public ulong ullAvailPhys;
     public ulong ullTotalPageFile;
     public ulong ullAvailPageFile;
     public ulong ullTotalVirtual;
     public ulong ullAvailVirtual;
     public ulong ullAvailExtendedVirtual;
     public MEMORYSTATUSEX()
     {
        this.dwLength = (uint)Marshal.SizeOf(typeof(NativeMethods.MEMORYSTATUSEX));
     }
  }


  [return: MarshalAs(UnmanagedType.Bool)]
  [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
  static extern bool GlobalMemoryStatusEx([In, Out] MEMORYSTATUSEX lpBuffer);
Run Code Online (Sandbox Code Playgroud)

然后使用像:

ulong installedMemory;
MEMORYSTATUSEX memStatus = new MEMORYSTATUSEX();
if( GlobalMemoryStatusEx( memStatus))
{ 
   installedMemory = memStatus.ullTotalPhys;
}
Run Code Online (Sandbox Code Playgroud)

或者您可以使用WMI(托管但速度较慢)来查询"Win32_ComputerSystem"类中的"TotalPhysicalMemory".

从joel-llamaduck.blogspot.com 编辑每条评论的固定代码

  • 代码有效,只有你不需要使用'NativeMethods'来获得对象的大小,你可以这样说:`this.dwLength =(uint)Marshal.SizeOf(this);`和它的工作方式相同(我在使用NativeMethods时遇到了麻烦,所以现在这个修复工作正常. (4认同)
  • 这是行不通的... long ramuse = (long)stat.TotalPhysical; long ramavailable = (long)stat.AvailablePhysical; long ramtotal = ramavailable + ramuse; int 百分比 = (int)( (float)ramuse / ramtotal * 100); 百分比告诉我“70”并且总数在不断变化,给予或接受 100。应该是 72% (2认同)
  • “NativeMethods”是类型的命名空间。如果您愿意,可以更改对 SizeOf 的调用。 (2认同)
  • @Corelgott 没用,因为它提供了最新信息?我的意思是,每次我查看天气频道时,它都会提供不同的信息,但我不会说它完全没用。我什至不确定如果这个函数每次都没有返回可能不同的信息,你会希望它做什么——它是否应该在第一次调用后“锁定”结果,然后返回陈旧数据?哪种方式更有用? (2认同)
  • 聚会有点晚了,但我偶然发现了这个帖子,这个答案不正确。GlobalMemoryStatusEx 不一定(通常不会)给出机器上安装的实际 RAM 量,它给出了操作系统可用的 RAM 量,该量几乎总是与由于驱动程序保留的内存等而安装的量不同. 要获得实际安装的 RAM 量,您需要调用 GetPhysicallyInstalledSystemMemory 函数,该函数返回正确的总 RAM。http://msdn.microsoft.com/en-us/library/windows/desktop/cc300158(v=vs.85).aspx (2认同)
  • 不跨平台! (2认同)

Rya*_*ndy 59

像上面提到的那样添加对Microsoft.VisualBasic.dll的引用.然后获得总物理内存就像这样简单(是的,我测试过它):

static ulong GetTotalMemoryInBytes()
{
    return new Microsoft.VisualBasic.Devices.ComputerInfo().TotalPhysicalMemory;
}
Run Code Online (Sandbox Code Playgroud)

  • @ppumkin,在什么版本的.NET中,以及在什么版本的Visual Studio中?当我在具有8 GB RAM的64位计算机上使用.NET 4.5在VS 2012中运行它时,它运行正常.我回来了8520327168. (3认同)
  • 在 x64 上工作正常。您正在使用 32 位 VS,它可能正在编译 32 位二进制文​​件,但不会看到完整的内存大小。 (2认同)
  • 在带有 C# .Net 4.6.1 的 Visual Studio 2017 中使用它时,我确实必须添加 Microsoft.VisualBasic 的引用才能使其工作。项目 > 添加参考 >> 程序集 > 检查 Microsoft.VisualBasic >> 确定 (2认同)

小智 29

如果您碰巧使用Mono,那么您可能有兴趣知道Mono 2.8(将于今年晚些时候发布)将有一个性能计数器,用于报告Mono运行的所有平台(包括Windows)上的物理内存大小.您可以使用以下代码片段检索计数器的值:

using System;
using System.Diagnostics;

class app
{
   static void Main ()
   {
       var pc = new PerformanceCounter ("Mono Memory", "Total Physical Memory");
       Console.WriteLine ("Physical RAM (bytes): {0}", pc.RawValue);
   }
}
Run Code Online (Sandbox Code Playgroud)

如果您对提供性能计数器的C代码感兴趣,可以在此处找到它.


sst*_*tan 26

这里的所有答案,包括已接受的答案,都将为您提供可用的RAM总量.这可能是OP想要的.

但是,如果您对获取已安装的 RAM 数量感兴趣,那么您将需要调用GetPhysicallyInstalledSystemMemory函数.

从链接中,在备注部分:

GetPhysicallyInstalledSystemMemory功能从计算机的SMBIOS固件表中检索物理安装的RAM量.这可能与GlobalMemoryStatusEx函数报告的数量不同,后者将MEMORYSTATUSEX结构的ullTotalPhys成员设置为可供操作系统使用的物理内存量.操作系统可用的内存量可能小于计算机中物理安装的内存量,因为BIOS和某些驱动程序可能会将内存保留为内存映射设备的I/O区域,从而使操作系统无法访问内存和应用程序.

示例代码:

[DllImport("kernel32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool GetPhysicallyInstalledSystemMemory(out long TotalMemoryInKilobytes);

static void Main()
{
    long memKb;
    GetPhysicallyInstalledSystemMemory(out memKb);
    Console.WriteLine((memKb / 1024 / 1024) + " GB of RAM installed.");
}
Run Code Online (Sandbox Code Playgroud)


BRA*_*mel 15

对于正在使用的用户.net Core 3.0,无需使用PInvoke平台即可获得可用的物理内存。本GC类增加了新的方法GC.GetGCMemoryInfo,它返回一个GCMemoryInfo Struct带有TotalAvailableMemoryBytes作为属性。此属性返回垃圾收集器的总可用内存。(与 MEMORYSTATUSEX 相同的值)

var gcMemoryInfo = GC.GetGCMemoryInfo();
installedMemory = gcMemoryInfo.TotalAvailableMemoryBytes;
// it will give the size of memory in MB
var physicalMemory = (double) installedMemory / 1048576.0;
Run Code Online (Sandbox Code Playgroud)

  • 仅供参考,如果您的应用程序是为 x86/32 位进程编译但在 64 位计算机上运行,​​那么这将不会返回安装的真实系统总内存。就我而言,返回的是 2 GB,而不是 32 GB。 (7认同)

zge*_*erd 11

另一种方法是使用.NET System.Management查询工具:

string Query = "SELECT Capacity FROM Win32_PhysicalMemory";
ManagementObjectSearcher searcher = new ManagementObjectSearcher(Query);

UInt64 Capacity = 0;
foreach (ManagementObject WniPART in searcher.Get())
{
    Capacity += Convert.ToUInt64(WniPART.Properties["Capacity"].Value);
}

return Capacity;
Run Code Online (Sandbox Code Playgroud)

  • 我喜欢这一个。无需引用“Microsoft.VisualBasic.Devices”。作为一行 `varCapacity = new ManagementObjectSearcher("SELECTCapacityFROMWin32_PhysicalMemory").Get().Cast<ManagementObject>().Sum(x => Convert.ToInt64(x.Properties["Capacity"].Value) ));` (2认同)

小智 6

您只需使用此代码即可获取这些信息,只需添加引用即可

using Microsoft.VisualBasic.Devices;
Run Code Online (Sandbox Code Playgroud)

并简单地使用以下代码

    private void button1_Click(object sender, EventArgs e)
    {
        getAvailableRAM();
    }

    public void getAvailableRAM()
    {
        ComputerInfo CI = new ComputerInfo();
        ulong mem = ulong.Parse(CI.TotalPhysicalMemory.ToString());
        richTextBox1.Text = (mem / (1024*1024) + " MB").ToString();
    }
Run Code Online (Sandbox Code Playgroud)


小智 5

你可以使用 WMI。发现一个片段。

Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" _ 
& strComputer & "\root\cimv2") 
Set colComputer = objWMIService.ExecQuery _
("Select * from Win32_ComputerSystem")

For Each objComputer in colComputer 
  strMemory = objComputer.TotalPhysicalMemory
Next
Run Code Online (Sandbox Code Playgroud)


小智 5

// use `/ 1048576` to get ram in MB
// and `/ (1048576 * 1024)` or `/ 1048576 / 1024` to get ram in GB
private static String getRAMsize()
{
    ManagementClass mc = new ManagementClass("Win32_ComputerSystem");
    ManagementObjectCollection moc = mc.GetInstances();
    foreach (ManagementObject item in moc)
    {
       return Convert.ToString(Math.Round(Convert.ToDouble(item.Properties["TotalPhysicalMemory"].Value) / 1048576, 0)) + " MB";
    }

    return "RAMsize";
}
Run Code Online (Sandbox Code Playgroud)