컴퓨터에있는 총 RAM 양은 어떻게 얻습니까?


88

C #을 사용하여 내 컴퓨터에있는 총 RAM 양을 얻고 싶습니다. PerformanceCounter를 사용하면 다음을 설정하여 사용 가능한 램의 양을 얻을 수 있습니다.

counter.CategoryName = "Memory";
counter.Countername = "Available MBytes";

그러나 총 메모리 양을 얻는 방법을 찾지 못하는 것 같습니다. 어떻게하면 되나요?

최신 정보:

MagicKat : 검색 할 때 봤는데 작동하지 않습니다. "어셈블리 또는 참조가 누락 되었습니까?". 나는 그것을 References에 추가하려고했지만 거기에는 보이지 않습니다.

답변:


62

Windows API 함수 GlobalMemoryStatusEx는 p / invoke를 사용하여 호출 할 수 있습니다.

  [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);

그런 다음 다음과 같이 사용하십시오.

ulong installedMemory;
MEMORYSTATUSEX memStatus = new MEMORYSTATUSEX();
if( GlobalMemoryStatusEx( memStatus))
{ 
   installedMemory = memStatus.ullTotalPhys;
}

또는 WMI (관리되지만 더 느림)를 사용 TotalPhysicalMemory하여 Win32_ComputerSystem클래스 에서 쿼리 할 수 ​​있습니다 .


2
작동하지 않습니다 ... long ramuse = (long) stat.TotalPhysical; long ramavailable = (long) stat.AvailablePhysical; 긴 ramtotal = ramavailable + ramuse; int percent = (int) ((float) ramuse / ramtotal * 100); 퍼센트는 나에게 "70"을 말하고 합계는 지속적으로 변하고 100을 주거나받습니다. 72 %가되어야합니다
Joel

5
코드는 작동합니다. 객체의 크기를 얻기 위해 'NativeMethods'를 사용할 필요는 없습니다. 간단히 다음 this.dwLength = (uint)Marshal.SizeOf(this);과 같이 말할 수 있습니다 . 동일하게 작동합니다 (NativeMethods를 사용하는 데 문제가있어서 이제이 수정이 작동합니다).
Cipi 2010

2
"NativeMethods"는 유형의 네임 스페이스입니다. 원하는 경우 SizeOf 호출을 변경할 수 있습니다.
Philip Rieck

2
@Corelgott 최신 정보를 제공하기 때문에 쓸모가 없습니까? 내 말은, 날씨 채널을 확인할 때마다 다른 정보를 제공하지만 완전히 쓸모 없다고 부르지는 않을 것입니다. 매번 잠재적으로 다른 정보를 반환하지 않는 경우이 함수가 무엇을해야할지 모르겠습니다. 첫 번째 호출 후에 결과를 "잠그고"그 후에 오래된 데이터를 반환해야합니까? 어떤면에서 더 유용할까요?
Philip Rieck

2
파티에 조금 늦었지만이 스레드에서 발생 했으며이 답변이 올바르지 않습니다. GlobalMemoryStatusEx는 컴퓨터에 설치된 실제 RAM 양을 반드시 제공하는 것은 아니며 (종종 제공하지 않을 수도 있음), OS에서 사용할 수있는 양을 제공합니다. 이는 드라이버 용 예약 된 메모리로 인해 설치된 양과 거의 항상 다릅니다. 설치된 RAM의 실제 양을 얻으려면 적절한 총 RAM을 반환하는 GetPhysicallyInstalledSystemMemory 함수를 호출해야합니다. msdn.microsoft.com/en-us/library/windows/desktop/…
Mike Johnson

182

Microsoft.VisualBasic및에 대한 참조를 추가합니다 using Microsoft.VisualBasic.Devices;.

ComputerInfo클래스는 당신이 필요로하는 모든 정보가 있습니다.


10
도대체 왜이 투표가 거부 되었습니까? 다시 투표했습니다! 이것이 가장 쉬운 방법이며 C #에서 가능합니다.
Paul Batum

54
+1 : 일부 사람들은 C #에서 Microsoft.VisualBasic 네임 스페이스를 참조하는 것을 싫어합니다. 실제로는 다른 모든 것의 일부로 설치되는 또 다른 어셈블리 일뿐입니다.
Bevan

2
8GB RAM이있는 Windows7 64 비트에서 음의 정크 값을 반환합니다. 그게 당신이 투표를받은 이유인가요?
Piotr Kula 2012 년

6
(new ComputerInfo ()). TotalPhysicalMemory 사용을 걱정하는 사람에게는 그보다 더 많은 메모리가있는 시스템에서 제대로 작동합니다. 반환 유형은 unsigned long이므로 (잘못된) 캐스트 없이는 음수를 사용할 수 없습니다.
Miles Strombach

6
var totalGBRam = Convert.ToInt32 ((new ComputerInfo (). TotalPhysicalMemory / (Math.Pow (1024, 3))) + 0.5);
Sean

63

위에서 언급 한 것처럼 Microsoft.VisualBasic.dll에 대한 참조를 추가합니다. 그런 다음 총 물리적 메모리를 얻는 것은 다음과 같이 간단합니다 (예, 테스트했습니다).

static ulong GetTotalMemoryInBytes()
{
    return new Microsoft.VisualBasic.Devices.ComputerInfo().TotalPhysicalMemory;
}

4
@ppumkin, 어떤 버전의 .NET에서 어떤 버전의 Visual Studio에서? 8GB RAM이있는 64 비트 컴퓨터에서 .NET 4.5를 사용하여 VS 2012에서 실행하면 제대로 작동합니다. 8520327168로 돌아옵니다.
Ryan Lundy

.NET 4, VS2010 32 비트 (Windows Pro 7 64 비트)
Piotr Kula

2
x64에서 잘 작동합니다. 전체 메모리 크기가 표시되지 않는 32 비트 바이너리를 컴파일하는 32 비트 VS를 사용하고 있습니다.
Lucas Teske 2014-08-22

2
C # .Net 4.6.1과 함께 Visual Studio 2017에서 이것을 사용할 때이 작업을 수행하려면 Microsoft.VisualBasic에 대한 참조를 추가해야했습니다. 프로젝트> 참조 추가 >> 어셈블리> Microsoft.VisualBasic 확인 >> 확인
WebLuke 2018 년

GetPhysicallyInstalledSystemMemory와 Microsoft.VisualBasic.Devices.ComputerInfo (). TotalPhysicalMemory new FileSizeStruct (34173231104) {31.8 GB} ByteCount : 34173231104 ByteSize : GB 크기 : 31.8 new FileSizeStruct (34359738368) {32 GB} ByteCount : 34359738368 GB 크기 : 32
fanuc_bob

36

허용되는 답변을 포함하여 여기에있는 모든 답변 은 사용 가능한 총 RAM 용량을 제공 합니다. 그리고 그것은 OP가 원했던 것일 수 있습니다.

그러나 설치된 RAM 의 양을 얻으 려면 GetPhysicallyInstalledSystemMemory 함수를 호출하는 것이 좋습니다.

링크의 비고 섹션에서 :

GetPhysicallyInstalledSystemMemory 기능은 컴퓨터의 SMBIOS 펌웨어 테이블에서 물리적으로 설치 RAM의 양을 검색합니다. 이는 MEMORYSTATUSEX 구조의 ullTotalPhys 멤버를 운영 체제에서 사용할 수있는 실제 메모리 양으로 설정 하는 GlobalMemoryStatusEx 함수에서 보고하는 양과 다를 수 있습니다. 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.");
}

1
감사합니다! 나는 정확히 이것을 찾고 있었지만 모든 곳에서 설치된 메모리가 아닌 사용 가능한 총 메모리를 찾는 방법 만 볼 수 있습니다.
SM

하지만 메인 머신에서 완벽하게 작동 함에도 불구하고 내 가상 머신에서는 잘 작동하지 않습니다.
SM

31

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

성능 카운터를 제공하는 C 코드에 관심이있는 경우 여기 에서 찾을 수 있습니다 .


ARM 시스템에서도 모든 Linux 시스템에서 잘 작동합니다.
harry4516

14

이를 수행하는 또 다른 방법은 .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;

내 컴퓨터에서 System.Management.ManagementException 메모리 부족이 발생합니다. 어떤 아이디어?
Amar

2
난이게 좋아. 참조 할 필요가 없습니다 Microsoft.VisualBasic.Devices. 그리고 한 줄짜리var Capacity = new ManagementObjectSearcher("SELECT Capacity FROM Win32_PhysicalMemory").Get().Cast<ManagementObject>().Sum(x => Convert.ToInt64(x.Properties["Capacity"].Value));
VDWWD

10

사용하는 사람들은 사용 가능한 물리적 메모리를 얻기 위해 플랫폼 .net Core 3.0을 사용할 필요가 없습니다 PInvoke. GC클래스는 새로운 방법을 추가했습니다 GC.GetGCMemoryInfo다시 발생 GCMemoryInfo StructTotalAvailableMemoryBytes속성으로합니다. 이 속성은 가비지 수집기에 사용할 수있는 총 메모리를 반환합니다 (MEMORYSTATUSEX와 동일한 값).

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

내가 가장 좋아하는 대답. 감사.
Matas Vaitkevicius

7

이 코드를 사용하여 정보를 얻을 수 있습니다. 참조를 추가하면됩니다.

using Microsoft.VisualBasic.Devices;

다음 코드를 사용하면됩니다.

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

.net 4.6 버전에서는 찾을 수 없습니다. ComputerInfo 네임 스페이스를 찾을 수 없음을 의미합니다. 훨씬 더 ... 네임 스페이스 'Devices'가 존재하지 않습니다.
gumuruh

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

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

참고 Set더 이상 VB.NET 필요하지 않습니다,이 VB6 코드는?
jrh

2

이 기능 ( ManagementQuery)은 Windows XP 이상에서 작동합니다.

private static string ManagementQuery(string query, string parameter, string scope = null) {
    string result = string.Empty;
    var searcher = string.IsNullOrEmpty(scope) ? new ManagementObjectSearcher(query) : new ManagementObjectSearcher(scope, query);
    foreach (var os in searcher.Get()) {
        try {
            result = os[parameter].ToString();
        }
        catch {
            //ignore
        }

        if (!string.IsNullOrEmpty(result)) {
            break;
        }
    }

    return result;
}

용법:

Console.WriteLine(BytesToMb(Convert.ToInt64(ManagementQuery("SELECT TotalPhysicalMemory FROM Win32_ComputerSystem", "TotalPhysicalMemory", "root\\CIMV2"))));

2
BytesToMb기능은 어디에서 왔습니까?
Cee McSharpface

@dlatikay 내부 기능입니다 : private static double BytesToMb (long bytes) {return Math.Round (bytes / 1024d / 1024d, 2); }
Lance

1

.Net 및 Mono와 호환 (Win10 / FreeBSD / CentOS로 테스트 됨)

Mono 및 .Net의 백업으로 ComputerInfo소스 코드 및 PerformanceCounters 사용 :

using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Security;

public class SystemMemoryInfo
{
    private readonly PerformanceCounter _monoAvailableMemoryCounter;
    private readonly PerformanceCounter _monoTotalMemoryCounter;
    private readonly PerformanceCounter _netAvailableMemoryCounter;

    private ulong _availablePhysicalMemory;
    private ulong _totalPhysicalMemory;

    public SystemMemoryInfo()
    {
        try
        {
            if (PerformanceCounterCategory.Exists("Mono Memory"))
            {
                _monoAvailableMemoryCounter = new PerformanceCounter("Mono Memory", "Available Physical Memory");
                _monoTotalMemoryCounter = new PerformanceCounter("Mono Memory", "Total Physical Memory");
            }
            else if (PerformanceCounterCategory.Exists("Memory"))
            {
                _netAvailableMemoryCounter = new PerformanceCounter("Memory", "Available Bytes");
            }
        }
        catch
        {
            // ignored
        }
    }

    public ulong AvailablePhysicalMemory
    {
        [SecurityCritical]
        get
        {
            Refresh();

            return _availablePhysicalMemory;
        }
    }

    public ulong TotalPhysicalMemory
    {
        [SecurityCritical]
        get
        {
            Refresh();

            return _totalPhysicalMemory;
        }
    }

    [SecurityCritical]
    [DllImport("Kernel32", CharSet = CharSet.Auto, SetLastError = true)]
    private static extern void GlobalMemoryStatus(ref MEMORYSTATUS lpBuffer);

    [SecurityCritical]
    [DllImport("Kernel32", CharSet = CharSet.Auto, SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    private static extern bool GlobalMemoryStatusEx(ref MEMORYSTATUSEX lpBuffer);

    [SecurityCritical]
    private void Refresh()
    {
        try
        {
            if (_monoTotalMemoryCounter != null && _monoAvailableMemoryCounter != null)
            {
                _totalPhysicalMemory = (ulong) _monoTotalMemoryCounter.NextValue();
                _availablePhysicalMemory = (ulong) _monoAvailableMemoryCounter.NextValue();
            }
            else if (Environment.OSVersion.Version.Major < 5)
            {
                var memoryStatus = MEMORYSTATUS.Init();
                GlobalMemoryStatus(ref memoryStatus);

                if (memoryStatus.dwTotalPhys > 0)
                {
                    _availablePhysicalMemory = memoryStatus.dwAvailPhys;
                    _totalPhysicalMemory = memoryStatus.dwTotalPhys;
                }
                else if (_netAvailableMemoryCounter != null)
                {
                    _availablePhysicalMemory = (ulong) _netAvailableMemoryCounter.NextValue();
                }
            }
            else
            {
                var memoryStatusEx = MEMORYSTATUSEX.Init();

                if (GlobalMemoryStatusEx(ref memoryStatusEx))
                {
                    _availablePhysicalMemory = memoryStatusEx.ullAvailPhys;
                    _totalPhysicalMemory = memoryStatusEx.ullTotalPhys;
                }
                else if (_netAvailableMemoryCounter != null)
                {
                    _availablePhysicalMemory = (ulong) _netAvailableMemoryCounter.NextValue();
                }
            }
        }
        catch
        {
            // ignored
        }
    }

    private struct MEMORYSTATUS
    {
        private uint dwLength;
        internal uint dwMemoryLoad;
        internal uint dwTotalPhys;
        internal uint dwAvailPhys;
        internal uint dwTotalPageFile;
        internal uint dwAvailPageFile;
        internal uint dwTotalVirtual;
        internal uint dwAvailVirtual;

        public static MEMORYSTATUS Init()
        {
            return new MEMORYSTATUS
            {
                dwLength = checked((uint) Marshal.SizeOf(typeof(MEMORYSTATUS)))
            };
        }
    }

    private struct MEMORYSTATUSEX
    {
        private uint dwLength;
        internal uint dwMemoryLoad;
        internal ulong ullTotalPhys;
        internal ulong ullAvailPhys;
        internal ulong ullTotalPageFile;
        internal ulong ullAvailPageFile;
        internal ulong ullTotalVirtual;
        internal ulong ullAvailVirtual;
        internal ulong ullAvailExtendedVirtual;

        public static MEMORYSTATUSEX Init()
        {
            return new MEMORYSTATUSEX
            {
                dwLength = checked((uint) Marshal.SizeOf(typeof(MEMORYSTATUSEX)))
            };
        }
    }
}

0

아무도 아직 GetPerformanceInfo 를 언급 하지 않았습니다. PInvoke 서명 을 사용할 수 있습니다.

이 기능을 사용하면 다음과 같은 시스템 전체 정보를 사용할 수 있습니다.

  • CommitTotal
  • CommitLimit
  • CommitPeak
  • PhysicalTotal
  • PhysicalAvailable
  • SystemCache
  • KernelTotal
  • KernelPaged
  • KernelNonpaged
  • 페이지 크기
  • HandleCount
  • ProcessCount
  • ThreadCount

PhysicalTotal값은 페이지 수이지만 OP가 찾고있는 것이므로 바이트로 변환하려면 PageSize반환 된 값을 곱합니다 .


0

.NIT는 전체에 액세스 할 수있는 메모리 양에 제한이 있습니다. 백분율이 있고 xp에서 2GB가 하드 천장이었습니다.

4GB를 사용할 수 있으며 2GB에 도달하면 앱이 종료됩니다.

또한 64 비트 모드에서는 시스템 외부에서 사용할 수있는 메모리의 비율이 있으므로 전체를 요청할 수 있는지 또는 이것이 특별히 보호되는지 확실하지 않습니다.


/아니/. 총 물리적 메모리는 물리적으로 설치된 실제 메모리를 의미합니다.
Matthew Flaschen

사실 DevelopingChris가 맞습니다. 4Gig의 Ram이있는 XP 시스템에서 GlobalMemoryStatusEx를 호출하면 3Gig 만 설치되어 있다고보고합니다.
epotter 2009-08-07

또한 WMI를 사용하여 Win32_ComputerSystem 또는 Win32_LogicalMemoryConfiguration에서 TotalPhysicalMemory를 쿼리하면 잘못된 결과가 생성됩니다.
epotter 2009-08-07

감사합니다. .net 라이브러리 이외의 정보에 대해 다른 소스를 사용해야한다는 질문을 이해하지 못하는 것이 아닙니다.
DevelopingChris

이 대답은 이치에 맞는 유일한 대답입니다. VisualBasic을 사용하여 Win 64 8Gb 램에서 이제 피곤했습니다. 나는 정크 음수 값을 얻습니다.
Piotr Kula 2012 년

-3
/*The simplest way to get/display total physical memory in VB.net (Tested)

public sub get_total_physical_mem()

    dim total_physical_memory as integer

    total_physical_memory=CInt((My.Computer.Info.TotalPhysicalMemory) / (1024 * 1024))
    MsgBox("Total Physical Memory" + CInt((My.Computer.Info.TotalPhysicalMemory) / (1024 * 1024)).ToString + "Mb" )
end sub
*/


//The simplest way to get/display total physical memory in C# (converted Form http://www.developerfusion.com/tools/convert/vb-to-csharp)

public void get_total_physical_mem()
{
    int total_physical_memory = 0;

    total_physical_memory = Convert.ToInt32((My.Computer.Info.TotalPhysicalMemory) /  (1024 * 1024));
    Interaction.MsgBox("Total Physical Memory" + Convert.ToInt32((My.Computer.Info.TotalPhysicalMemory) / (1024 * 1024)).ToString() + "Mb");
}

6
온라인 Visual Basic에서 CShap으로의 변환기 덕분 일 수 있습니다.
Nick Binnet 2013-06-21
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.