Как получить общий объем оперативной памяти компьютера?

Используя C#, я хочу получить общий объем оперативной памяти моего компьютера. С помощью PerformanceCounter я могу получить количество доступной оперативной памяти, установив:

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

Но я не могу найти способ получить общий объем памяти. Как бы я это сделал?

Обновлять:

MagicKat: Я видел это, когда искал, но это не работает - «Вам не хватает сборки или ссылки?». Я хотел добавить это в список литературы, но не вижу его там.

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
89
0
136 475
15
Перейти к ответу Данный вопрос помечен как решенный

Ответы 15

.NIT имеет ограничение на общий объем памяти, к которому он может получить доступ. Там процент, а то 2 ГБ в xp были жестким потолком.

У вас может быть 4 ГБ в нем, и это убьет приложение, когда оно достигнет 2 ГБ.

Также в 64-битном режиме есть процент памяти, который вы можете использовать вне системы, поэтому я не уверен, можете ли вы запросить все это целиком или это специально защищено.

/Нет/. Общая физическая память означает физически установленную фактическую память.

Matthew Flaschen 23.05.2009 16:51

Собственно, DevelopingChris прав. Если вы вызовете GlobalMemoryStatusEx на машине XP с 4 гигабайтами оперативной памяти, он сообщит, что установлено только 3 гигабайта.

epotter 07.08.2009 21:46

Кроме того, использование WMI для запроса TotalPhysicalMemory в Win32_ComputerSystem или Win32_LogicalMemoryConfiguration также дает неверный результат.

epotter 07.08.2009 22:03

спасибо, дело не в том, что я не понимаю вопроса, что вы должны использовать другой источник информации, кроме библиотеки .net.

DevelopingChris 08.08.2009 00:20

Этот ответ - единственный, который имеет смысл. Я устал теперь на Win 64 8Gb ram с использованием VisualBasic. Я получаю ненужные отрицательные значения.

Piotr Kula 15.09.2012 19:46

Добавьте ссылку на Microsoft.VisualBasic и using Microsoft.VisualBasic.Devices;.

Класс ComputerInfo содержит всю необходимую информацию.

Почему, черт возьми, это было отклонено? Проголосовал обратно! Это самый простой способ сделать это, и да, вы можете это сделать с C#.

Paul Batum 20.09.2008 00:12

+1: Некоторые люди не любят ссылаться на пространство имен Microsoft.VisualBasic из C#, хотя на самом деле это просто еще одна сборка, установленная как часть всего остального.

Bevan 20.01.2009 23:00

Возвращает отрицательное значение нежелательной почты в 64-битной Windows7 с оперативной памятью 8 ГБ. Вот почему вы проголосовали?

Piotr Kula 15.09.2012 19:44

Для тех, кто с подозрением относится к использованию (new ComputerInfo ()). TotalPhysicalMemory, он отлично работает в системе с еще большим объемом памяти. Его возвращаемый тип - unsigned long, поэтому отрицательное число невозможно без (недопустимого) приведения.

Miles Strombach 11.07.2015 03:04

var totalGBRam = Convert.ToInt32 ((new ComputerInfo (). TotalPhysicalMemory / (Math.Pow (1024, 3))) + 0,5);

Sean 23.06.2017 16:17

Вы можете использовать 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 18.01.2017 22:20
Ответ принят как подходящий

Функцию 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.

Это работает! Спасибо. Одно но: TotalPhysical дает, сколько используется, AvailablePhysical дает, сколько осталось. Так что получите реальную сумму, вы должны сложить ее. Спасибо!

Joel 20.09.2008 00:17

Это не работает ... long ramuse = (long) stat.TotalPhysical; long ramavailable = (длинный) stat.AvailablePhysical; длинный ramtotal = ramavailable + ramuse; int процент = (int) ((float) ramuse / ramtotal * 100); процент говорит мне "70", а общее количество постоянно меняется, плюс-минус 100. Должно быть 72%

Joel 20.09.2008 00:29

Изменен на GlobalMemoryStatusEx - GlobalMemoryStatus использовал uint и имел проблемы - более 4 ГБ просто давали бы мусор, но с 2 ГБ до 4 ГБ округлялось до 2 ГБ как для доступности, так и для всего.

Philip Rieck 20.09.2008 00:50

Код работает, только вам не нужно использовать NativeMethods для получения размера объекта, вы можете просто сказать так: this.dwLength = (uint)Marshal.SizeOf(this);, и он работает так же (у меня были проблемы с использованием NativeMethods, поэтому теперь это исправление работает).

Cipi 14.04.2010 14:02

«NativeMethods» - это пространство имен типа. Вызов SizeOf можно изменить, если хотите.

Philip Rieck 14.04.2010 17:11

Что такое GlobalMemoryStatusEx? Кажется, я не могу найти его ссылки. О, чувак, я получил 0 за все. Почему так сложно получить информацию о памяти и процессоре в C#; Блайм

Piotr Kula 15.09.2012 19:52

Цитата из MSDN: «Информация, возвращаемая функцией GlobalMemoryStatusEx, непостоянна. Нет гарантии, что два последовательных вызова этой функции вернут одну и ту же информацию». msdn.microsoft.com/en-us/library/windows/desktop/… - На мой взгляд, такой вид делает функцию совершенно бесполезной.

Tobias Boschek 24.06.2013 13:20

@Corelgott Бесполезен, потому что он дает актуальную информацию? Я имею в виду, что каждый раз, когда я проверяю погодный канал, он дает разную информацию, но я бы не стал называть это совершенно бесполезным. Я даже не уверен, что бы вы хотели, чтобы эта функция делала, если бы она не возвращала каждый раз потенциально разную информацию - должна ли она «блокировать» результаты после первого вызова, а затем возвращать устаревшие данные после этого? Каким образом это было бы более полезно?

Philip Rieck 24.06.2013 18:07

Немного опоздал на вечеринку, но я наткнулся на эту тему, и этот ответ неверен. GlobalMemoryStatusEx не обязательно (и часто не дает) дает фактический объем оперативной памяти, установленной на машине, он дает объем, доступный для ОС, который почти всегда отличается от установленного объема из-за зарезервированной памяти для драйверов и т. д. Чтобы получить фактический объем установленной ОЗУ, вам нужно вызвать функцию GetPhysicallyInstalledSystemMemory, которая возвращает надлежащий общий объем ОЗУ. msdn.microsoft.com/en-us/library/windows/desktop/…

Mike Johnson 21.10.2014 04:37

Можете ли вы использовать это в Windows CE? Обычно вы можете использовать PInvoke для coredll.dll или kernel.dll, но они не работают. В статье MSDN для GlobalMemoryStatusEx не говорится, доступен ли он для WinCE, поэтому я предполагаю, что нет.

AlainD 23.04.2015 13:54

Не кроссплатформенный!

Stephen Buck 17.05.2019 17:12

Добавьте ссылку на Microsoft.VisualBasic.dll, как упоминалось выше. Тогда получить общую физическую память очень просто (да, я это тестировал):

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

@ppumkin, в какой версии .NET и в какой версии Visual Studio? Когда я запускаю его в VS 2012 с использованием .NET 4.5 на 64-битной машине с 8 ГБ ОЗУ, он работает нормально. Возвращаю 8520327168.

Ryan Lundy 01.02.2013 22:08

.NET 4, VS2010 32-разрядная версия на Windows Pro 7 64-разрядная версия

Piotr Kula 02.02.2013 02:07

Отлично работает на x64. Вы используете 32-битный VS, который, вероятно, компилирует 32-битные двоичные файлы, которые не видят полный размер памяти.

Lucas Teske 22.08.2014 08:01

При использовании этого в Visual Studio 2017 с C# .Net 4.6.1 мне пришлось добавить ссылку на Microsoft.VisualBasic, чтобы заставить это работать. Проект> Добавить ссылку >> Сборки> Проверить Microsoft.VisualBasic >> ОК

WebLuke 02.05.2018 18:01

Я заметил разницу между GetPhysicallyInstalledSystemMemory и Microsoft.VisualBasic.Devices.ComputerInfo (). TotalPhysicalMe mory new FileSizeStruct (34173231104) {31,8 ГБ} ByteCount: 34173231104 ByteSize: GB Размер: 31,8 NewteCount (размер файла) 346835335} ByteSize: 31,8 newteCount (размер файла) 346835335} ByteSize: 31,8 новый размер FileCount (размер файла) 3468353 ГБ ByteSize: GB Размер: 32

fanuc_bob 04.05.2018 23:55

Если вы используете 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, который предоставляет счетчик производительности, его можно найти здесь.

отлично работает в любой системе Linux, даже в системах ARM.

harry4516 08.01.2017 15:47

@ harry4516 в моей системе Ubuntu PerformanceCounter не поддерживается

Carlos Liu 29.12.2020 11:18

/*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");
}

Это может быть благодаря онлайн-конвертеру Visual Basic в CSharp.

Nick Binnet 22.06.2013 00:35

вы можете просто использовать этот код для получения этой информации, просто добавьте ссылку

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 не найдено. даже больше ... пространства имен "Устройства" не существует.

gumuruh 13.05.2020 10:46

Другой способ сделать это - использовать средства запросов .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 03.08.2017 18:39

Мне нравится этот. Ссылка на Microsoft.VisualBasic.Devices не требуется. И как однострочник var Capacity = new ManagementObjectSearcher("SELECT Capacity FROM Win32_PhysicalMemory").Get().Cast<ManagementObject>().Sum(x => Convert.ToInt64(x.Properties["Capacity"].Value));

VDWWD 02.08.2019 21:22

Еще никто не упомянул GetPerformanceInfo. Подписи PInvoke доступны.

Эта функция делает доступной следующую общесистемную информацию:

  • CommitTotal
  • CommitLimit
  • CommitPeak
  • PhysicalTotal
  • Физический Доступный
  • SystemCache
  • KernelTotal
  • KernelPaged
  • Ядро
  • Размер страницы
  • HandleCount
  • ProcessCount
  • Число потоков

PhysicalTotal - это то, что ищет OP, хотя значение - это количество страниц, поэтому для преобразования в байты умножьте на возвращенное значение PageSize.

Эта функция (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"))));

откуда взялась эта функция BytesToMb?

Cee McSharpface 19.01.2017 00:08

@dlatikay это внутренняя функция: частный статический двойной BytesToMb (длинные байты) {return Math.Round (bytes / 1024d / 1024d, 2); }

Lance 19.01.2017 11:51

Все ответы здесь, включая принятый, дадут вам общий объем RAM имеется в наличии для использования. И, возможно, это было то, что хотел OP.

Но если вас интересует объем оперативной памяти установлены, тогда вам нужно будет вызвать функцию GetPhysicallyInstalledSystemMemory.

По ссылке в разделе "Примечания":

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.

Образец кода:

[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.");
}
Спасибо! I was looking for exactly this but everywhere I can only see how to find the total available memory rather than the installed one.
S. M. 17.12.2018 18:30

Однако на моей виртуальной машине он не работает, хотя на основной он работает отлично.

S. M. 17.12.2018 19:10

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

Совместимость с .Net и Mono (протестировано с Win10 / FreeBSD / CentOS)

Использование исходного кода ComputerInfo и PerformanceCounter для Mono и в качестве резервной копии для .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)))
            };
        }
    }
}

Тем, кто использует .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;

Мой любимый ответ. Спасибо.

Matas Vaitkevicius 20.04.2020 18:57

Другие вопросы по теме