How do you get total amount of RAM the computer has?
Asked Answered
A

18

98

Using C#, I want to get the total amount of RAM that my computer has. With the PerformanceCounter I can get the amount of Available ram, by setting:

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

But I can't seem to find a way to get the total amount of memory. How would I go about doing this?

Update:

MagicKat: I saw that when I was searching, but it doesn't work - "Are you missing an assembly or reference?". I've looked to add that to the References, but I don't see it there.

Avunculate answered 19/9, 2008 at 20:0 Comment(0)
K
67

The Windows API function GlobalMemoryStatusEx can be called with 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);

Then use like:

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

Or you can use WMI (managed but slower) to query TotalPhysicalMemory in the Win32_ComputerSystem class.

Ketosis answered 19/9, 2008 at 20:9 Comment(11)
This is working! Thanks. One thing though - TotalPhysical is giving how much is in use, AvailablePhysical is giving how much is left. So get the real total, you have to add those up. Thanks!Avunculate
That's not working... long ramuse = (long)stat.TotalPhysical; long ramavailable = (long)stat.AvailablePhysical; long ramtotal = ramavailable + ramuse; int percent = (int)( (float)ramuse / ramtotal * 100); percent is telling me "70" and total is constantly changing, give or take 100. should be 72%Avunculate
Changed to GlobalMemoryStatusEx - GlobalMemoryStatus used uint and had problems - over 4GB would simply give garbage, but from 2GB-4GB would be rounded down to 2G for both avail and total.Ketosis
The code works, only you dont need to use 'NativeMethods' to get the size of the object, you simply can say like this: this.dwLength = (uint)Marshal.SizeOf(this); and it works the same (I had trouble with using NativeMethods so this fix now works).Forewarn
"NativeMethods" is the namespace of the type. The call to SizeOf can be changed if you prefer.Ketosis
What is GlobalMemoryStatusEx? I cannot seem to find its refernce. Oh Man i get 0 on it all. Why is ti so freaking difficult to get memeory and cpu info in C#; blymeWinkler
Quote from MSDN: "The information returned by the GlobalMemoryStatusEx function is volatile. There is no guarantee that two sequential calls to this function will return the same information." msdn.microsoft.com/en-us/library/windows/desktop/… - In my opinion this kind of renders the function totally uselessSpaceless
@Corelgott Useless because it gives up to date information? I mean, everytime I check the weather channel it gives different information, but I wouldn't go so far as to call it totally useless. I'm not even sure what you would want this function to do if it didn't return potentially different information each time - should it "lock" the results after the first invocation and then return stale data after that? In what way would that be more useful?Ketosis
A bit late to the party but I happened upon this thread and this answer is not correct. GlobalMemoryStatusEx doesn't necessarily (and often won't) give the actual amount of RAM installed on the machine, it gives the amount that is available to the OS which is almost always different than the amount installed due to reserved memory for drivers, etc. To get the actual amount of RAM installed you would want to call the GetPhysicallyInstalledSystemMemory function which returns the proper total RAM. msdn.microsoft.com/en-us/library/windows/desktop/…Eatables
Can you use this on Windows CE? Typically you can PInvoke these on coredll.dll or kernel.dll, but these fail. The MSDN article for GlobalMemoryStatusEx doesn't say whether its available for WinCE, so I'm guessing not.Leptorrhine
Not cross-platform!Mccombs
B
189

Add a reference to Microsoft.VisualBasic and a using Microsoft.VisualBasic.Devices;.

The ComputerInfo class has all the information that you need.

Bechuanaland answered 19/9, 2008 at 20:6 Comment(7)
Why on earth was this voted down? Voted back up! This is the easiest way to do it, and yes you can this from C#.Lazulite
+1: Some people have an aversion to referencing the Microsoft.VisualBasic namespace from C#, even though it's really just another assembly that's installed as a part of everything else.Karmakarmadharaya
Return negative junk value on Windows7 64bit with 8gb ram. Thats why you got down voted?Winkler
For anyone leery of using (new ComputerInfo()).TotalPhysicalMemory, it works fine on a system with even more memory than that. Its return type is unsigned long, so a negative number is not possible without an (invalid) cast.Transpose
var totalGBRam = Convert.ToInt32((new ComputerInfo().TotalPhysicalMemory / (Math.Pow(1024, 3))) + 0.5);Goulder
The Devices namespace has been removed from .NET Core 3.0 onwards, so this cannot be used on newer versions.Buroker
The Microsoft.VisualBasic namespace has no ComputerInfo class in .Net Framework 4.8. Also I was hoping to find a cross-platform (mono) solutionOversell
K
67

The Windows API function GlobalMemoryStatusEx can be called with 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);

Then use like:

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

Or you can use WMI (managed but slower) to query TotalPhysicalMemory in the Win32_ComputerSystem class.

Ketosis answered 19/9, 2008 at 20:9 Comment(11)
This is working! Thanks. One thing though - TotalPhysical is giving how much is in use, AvailablePhysical is giving how much is left. So get the real total, you have to add those up. Thanks!Avunculate
That's not working... long ramuse = (long)stat.TotalPhysical; long ramavailable = (long)stat.AvailablePhysical; long ramtotal = ramavailable + ramuse; int percent = (int)( (float)ramuse / ramtotal * 100); percent is telling me "70" and total is constantly changing, give or take 100. should be 72%Avunculate
Changed to GlobalMemoryStatusEx - GlobalMemoryStatus used uint and had problems - over 4GB would simply give garbage, but from 2GB-4GB would be rounded down to 2G for both avail and total.Ketosis
The code works, only you dont need to use 'NativeMethods' to get the size of the object, you simply can say like this: this.dwLength = (uint)Marshal.SizeOf(this); and it works the same (I had trouble with using NativeMethods so this fix now works).Forewarn
"NativeMethods" is the namespace of the type. The call to SizeOf can be changed if you prefer.Ketosis
What is GlobalMemoryStatusEx? I cannot seem to find its refernce. Oh Man i get 0 on it all. Why is ti so freaking difficult to get memeory and cpu info in C#; blymeWinkler
Quote from MSDN: "The information returned by the GlobalMemoryStatusEx function is volatile. There is no guarantee that two sequential calls to this function will return the same information." msdn.microsoft.com/en-us/library/windows/desktop/… - In my opinion this kind of renders the function totally uselessSpaceless
@Corelgott Useless because it gives up to date information? I mean, everytime I check the weather channel it gives different information, but I wouldn't go so far as to call it totally useless. I'm not even sure what you would want this function to do if it didn't return potentially different information each time - should it "lock" the results after the first invocation and then return stale data after that? In what way would that be more useful?Ketosis
A bit late to the party but I happened upon this thread and this answer is not correct. GlobalMemoryStatusEx doesn't necessarily (and often won't) give the actual amount of RAM installed on the machine, it gives the amount that is available to the OS which is almost always different than the amount installed due to reserved memory for drivers, etc. To get the actual amount of RAM installed you would want to call the GetPhysicallyInstalledSystemMemory function which returns the proper total RAM. msdn.microsoft.com/en-us/library/windows/desktop/…Eatables
Can you use this on Windows CE? Typically you can PInvoke these on coredll.dll or kernel.dll, but these fail. The MSDN article for GlobalMemoryStatusEx doesn't say whether its available for WinCE, so I'm guessing not.Leptorrhine
Not cross-platform!Mccombs
G
65

Add a reference to Microsoft.VisualBasic.dll, as someone mentioned above. Then getting total physical memory is as simple as this (yes, I tested it):

static ulong GetTotalMemoryInBytes()
{
    return new Microsoft.VisualBasic.Devices.ComputerInfo().TotalPhysicalMemory;
}
Grande answered 19/9, 2008 at 21:43 Comment(5)
@ppumkin, in what version of .NET, and in what version of Visual Studio? When I run it in VS 2012 using .NET 4.5 on a 64-bit machine with 8 GB of RAM, it works fine. I get back 8520327168.Grande
.NET 4, VS2010 32bit on Windows Pro 7 64bitWinkler
Works fine on x64.You are using a 32 bit VS that is probably compiling 32 bit binaries that wont see full memory size.Bethesde
When using this in Visual Studio 2017 with C# .Net 4.6.1, I did have to add a reference for Microsoft.VisualBasic to get this to work. Project > Add Reference >> Assemblies > Check Microsoft.VisualBasic >> OKGloom
I noticed a difference between GetPhysicallyInstalledSystemMemory and Microsoft.VisualBasic.Devices.ComputerInfo().TotalPhysicalMemory new FileSizeStruct(34173231104) {31.8 GB} ByteCount: 34173231104 ByteSize: GB Size: 31.8 new FileSizeStruct(34359738368) {32 GB} ByteCount: 34359738368 ByteSize: GB Size: 32Teresaterese
C
45

All the answers here, including the accepted one, will give you the total amount of RAM available for use. And that may have been what OP wanted.

But if you are interested in getting the amount of installed RAM, then you'll want to make a call to the GetPhysicallyInstalledSystemMemory function.

From the link, in the Remarks section:

The GetPhysicallyInstalledSystemMemory function retrieves the amount of physically installed RAM from the computer's SMBIOS firmware tables. This can differ from the amount reported by the GlobalMemoryStatusEx function, which sets the ullTotalPhys member of the MEMORYSTATUSEX structure to the amount of physical memory that is available for the operating system to use. The amount of memory available to the operating system can be less than the amount of memory physically installed in the computer because the BIOS and some drivers may reserve memory as I/O regions for memory-mapped devices, making the memory unavailable to the operating system and applications.

Sample code:

[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.");
}
Configuration answered 5/12, 2015 at 3:29 Comment(2)
Thank you! I was looking for exactly this but everywhere I can only see how to find the total available memory rather than the installed one.Kbp
It doesn't work well on my virtual machine though, despite functioning perfectly on the main one.Kbp
R
34

For those who are using .net Core 3.0 there is no need to use PInvoke platform in order to get the available physical memory. The GC class has added a new method GC.GetGCMemoryInfo that returns a GCMemoryInfo Struct with TotalAvailableMemoryBytes as a property. This property returns the total available memory for the garbage collector.(same value as MEMORYSTATUSEX)

var gcMemoryInfo = GC.GetGCMemoryInfo();
long installedMemory = gcMemoryInfo.TotalAvailableMemoryBytes;
// it will give the size of memory in MB
var physicalMemory = (double) installedMemory / 1048576.0;
Roil answered 27/11, 2019 at 15:5 Comment(4)
My favorite answer. Thanks.Bicarb
FYI, if your app is compiled for x86 / 32-bit process but running on a 64-bit machine, then this will not return the true total system memory installed. In my case, instead of returning 32 GB it returned 2 GB.Heliogravure
Note that you'll also need a 'using system;' for this code to work.Fuliginous
This does give installed capacity on local machine, however when this piece of code is inside Azure Function, it is not giving correct value, something to be aware of.Timoshenko
M
32

If you happen to be using Mono, then you might be interested to know that Mono 2.8 (to be released later this year) will have a performance counter which reports the physical memory size on all the platforms Mono runs on (including Windows). You would retrieve the value of the counter using this code snippet:

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

If you are interested in C code which provides the performance counter, it can be found here.

Misname answered 16/4, 2010 at 17:34 Comment(2)
works fine on any linux system, even on ARM systems.Saloma
@Saloma on my Ubuntu system, PerformanceCounter is not supportedLowminded
K
16

Another way to do this, is by using the .NET System.Management querying facilities:

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;
Kneepan answered 24/6, 2014 at 20:21 Comment(2)
This is throwing a System.Management.ManagementException Out of Memory on my machine. Any ideas?Splatter
I like this one. No need to reference Microsoft.VisualBasic.Devices. And as one-liner var Capacity = new ManagementObjectSearcher("SELECT Capacity FROM Win32_PhysicalMemory").Get().Cast<ManagementObject>().Sum(x => Convert.ToInt64(x.Properties["Capacity"].Value));Dorman
P
7

you can simply use this code to get those information, just add the reference

using Microsoft.VisualBasic.Devices;

and the simply use the following code

    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();
    }
Pahoehoe answered 31/3, 2014 at 4:49 Comment(1)
not found in .net 4.6 version. I mean it gives ComputerInfo namespace is not found. even more... namespace 'Devices' is doesnt exist.Forwarder
J
6
// 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";
}
Johnstone answered 20/1, 2016 at 12:28 Comment(0)
H
5

You could use 'WMI'.

I found a 'snippet'.

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
Hamlani answered 19/9, 2008 at 20:8 Comment(1)
Note that Set is no longer needed for VB.NET, is this VB6 code?Polysyllable
C
4

Solution working on Linux (.Net Core). Inspired by GitHub/Hardware.Info. Optimized to have minimal memory allocation and avg retrieval takes 0.020 ms.

private static readonly object _linuxMemoryLock = new();
private static readonly char[] _arrayForMemInfoRead = new char[200];

public static void GetBytesCountOnLinux(out ulong availableBytes, out ulong totalBytes)
{
    lock (_linuxMemoryLock) // lock because of reusing static fields due to optimization
    {
        totalBytes = GetBytesCountFromLinuxMemInfo(token: "MemTotal:", refreshFromFile: true);
        availableBytes = GetBytesCountFromLinuxMemInfo(token: "MemAvailable:", refreshFromFile: false);
    }
}

private static ulong GetBytesCountFromLinuxMemInfo(string token, bool refreshFromFile)
{
    // NOTE: Using the linux file /proc/meminfo which is refreshed frequently and starts with:
    //MemTotal:        7837208 kB
    //MemFree:          190612 kB
    //MemAvailable:    5657580 kB

    var readSpan = _arrayForMemInfoRead.AsSpan();

    if (refreshFromFile)
    {
        using var fileStream = new FileStream("/proc/meminfo", FileMode.Open, FileAccess.Read, FileShare.ReadWrite);

        using var reader = new StreamReader(fileStream, Encoding.UTF8, leaveOpen: true);

        reader.ReadBlock(readSpan);
    }

    var tokenIndex = readSpan.IndexOf(token);

    var fromTokenSpan = readSpan.Slice(tokenIndex + token.Length);

    var kbIndex = fromTokenSpan.IndexOf("kB");

    var notTrimmedSpan = fromTokenSpan.Slice(0, kbIndex);

    var trimmedSpan = notTrimmedSpan.Trim(' ');

    var kBytesCount = ulong.Parse(trimmedSpan);

    var bytesCount = kBytesCount * 1024;

    return bytesCount;
}

Linux and Windows together - for easy copy paste. Windows code taken from the accepted answer.

public static void GetRamBytes(out ulong availableBytes, out ulong totalBytes)
{
    if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
    {
        GetBytesCountOnLinux(out availableBytes, out totalBytes);
    }
    else if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
    {
        GetBytesCountOnWindows(out availableBytes, out totalBytes);
    }
    else
    {
        throw new NotImplementedException("Not implemented for OS: " + Environment.OSVersion);
    }
}

private static readonly object _winMemoryLock = new();
private static readonly MEMORYSTATUSEX _memStatus = new();

private static void GetBytesCountOnWindows(out ulong availableBytes, out ulong totalBytes)
{
    lock (_winMemoryLock) // lock because of reusing the static class _memStatus
    {
        GlobalMemoryStatusEx(_memStatus);

        availableBytes = _memStatus.ullAvailPhys;
        totalBytes = _memStatus.ullTotalPhys;
    }
}

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

[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern bool GlobalMemoryStatusEx([In] [Out] MEMORYSTATUSEX lpBuffer);
Corroborant answered 17/11, 2022 at 8:58 Comment(0)
B
2

This function (ManagementQuery) works on Windows XP and later:

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

Usage:

Console.WriteLine(BytesToMb(Convert.ToInt64(ManagementQuery("SELECT TotalPhysicalMemory FROM Win32_ComputerSystem", "TotalPhysicalMemory", "root\\CIMV2"))));
Bernardo answered 29/10, 2015 at 11:41 Comment(2)
where does that BytesToMb function come from?Hereditary
@dlatikay it's inner fuction: private static double BytesToMb(long bytes) { return Math.Round(bytes / 1024d / 1024d, 2); }Bernardo
I
2

Compatible with .Net and Mono (tested with Win10/FreeBSD/CentOS)

Using ComputerInfo source code and PerformanceCounters for Mono and as backup for .Net:

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)))
            };
        }
    }
}
Impressment answered 27/10, 2018 at 0:24 Comment(0)
F
0

.NET has a memory amount limit that it can access. In Windows XP 2GB was the "hard ceiling". For instance: You could have 4 GB in it, and it would kill the app when it hit 2GB.

Also in 64 bit mode, there is a percentage of memory you can use out of the system, so I'm not sure if you can ask for the whole thing or if this is specifically guarded against.

Forestforestage answered 19/9, 2008 at 20:3 Comment(5)
/No/. Total physical memory means the actual memory physically installed.Desist
Actually, DevelopingChris is correct. If you call GlobalMemoryStatusEx on a XP machine with 4 Gig of Ram, it will report that there is only 3 Gig installed.Durra
Also, using WMI to query TotalPhysicalMemory in Win32_ComputerSystem or Win32_LogicalMemoryConfiguration also produces the wrong result.Durra
thank you, its not that I don't understand the question its that you have to use a different source for the information other than a .net library.Forestforestage
This answer is the only one that makes sense. I tired it now on Win 64 8Gb ram using VisualBasic referenced. I get junk negative values.Winkler
A
0

Nobody has mentioned GetPerformanceInfo yet. PInvoke signatures are available.

This function makes the following system-wide information available:

  • CommitTotal
  • CommitLimit
  • CommitPeak
  • PhysicalTotal
  • PhysicalAvailable
  • SystemCache
  • KernelTotal
  • KernelPaged
  • KernelNonpaged
  • PageSize
  • HandleCount
  • ProcessCount
  • ThreadCount

PhysicalTotal is what the OP is looking for, although the value is the number of pages, so to convert to bytes, multiply by the PageSize value returned.

Arwood answered 22/10, 2014 at 18:50 Comment(0)
D
-2

Here is another, much more simply way, using .net:

// total memory
long totalPhysicalMemory = My.Computer.Info.TotalPhysicalMemory;

// unused memory
long availablePhysicalMemory = My.Computer.Info.AvailablePhysicalMemory;

// used memory
long usedMemory = totalPhysicalMemory - availablePhysicalMemory;
Disrespect answered 31/10, 2022 at 3:55 Comment(2)
What namespace is that from? Is using a library?File
documented here: learn.microsoft.com/en-us/dotnet/api/… - but its tied to vb.net so perhaps why this response is not getting any love :-)Disrespect
M
-3

var ram = new ManagementObjectSearcher("select * from Win32_PhysicalMemory") .Get().Cast<ManagementObject>().First();

|

var a = Convert.ToInt64(ram["Capacity"]) / 1024 / 1024 / 1024;

(richiede System.Managment.dll come riferimento, testato su C# con Framework 4.7.2)

questa procedura salva in "a" la ram totale presente in GB


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

|

var b = Convert.ToDecimal(memory()) / 1024 / 1024 / 1024;

(richiede Microsoft.VisualBasics.dll come riferimento, testato su C# Framework 4.7.2)

questa procedura salva in "b" il valore della ram in GB effettivamente disponibile


Manslaughter answered 25/3, 2021 at 17:1 Comment(1)
You should write the question in English.Penknife
D
-4
/*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");
}
Dutchman answered 5/5, 2012 at 13:57 Comment(1)
That might be thanks to online Visual Basic to CShap converters.Vocabulary

© 2022 - 2024 — McMap. All rights reserved.