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

StackOverflow https://stackoverflow.com/questions/105031

  •  01-07-2019
  •  | 
  •  

Вопрос

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

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

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

Обновить:

Волшебница:Я видел это, когда искал, но это не работает - "Вам не хватает сборки или ссылки?".Я хотел добавить это к Ссылкам, но я там этого не вижу.

Это было полезно?

Решение

Способ 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);

Затем используйте like:

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

Или вы можете использовать WMI (управляемый, но более медленный) для запроса "TotalPhysicalMemory" в классе "Win32_ComputerSystem".

Редактировать исправлен код для каждого комментария от joel-llamaduck.blogspot.com

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

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

Тот Самый ComputerInfo в классе есть вся информация, которая вам нужна.

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

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

Если вы используете 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);
   }
}

Если вас интересует код на языке Си, который предоставляет счетчик производительности, его можно найти здесь.

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

Но если вы заинтересованы в получении суммы установленный RAM, затем вам захочется позвонить в Получитьфизически установленную системную память функция.

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

Тот Самый Получитьфизически установленную системную память функция извлекает объем физически установленной оперативной памяти из таблиц встроенного программного обеспечения SMBIOS компьютера.Эта сумма может отличаться от суммы, указанной Глобальная память о статусе функция, которая устанавливает для элемента ULTOTALPHYS структуры MEMORYSTATUSEX значение объема физической памяти, который доступен для использования операционной системой. Объем памяти, доступный операционной системе, может быть меньше объема памяти, физически установленного на компьютере поскольку BIOS и некоторые драйверы могут резервировать память в качестве областей ввода-вывода для устройств с отображением памяти, что делает память недоступной для операционной системы и приложений.

Пример кода:

[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.");
}

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

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

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

Вы могли бы использовать 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
// 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";
}

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

Никто не упоминал Получите performanceinfo пока. Подписи PInvoke доступны.

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

  • Итоговый показатель
  • Ограничение на совершение
  • Совершить пик
  • Физический итог
  • Физическая доступность
  • Системный кэш
  • Общий объем ядра
  • Выгруженное ядро
  • Ядро не загружено
  • Размер страницы
  • Количество обработанных данных
  • Количество процессов
  • Количество потоков

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

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

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

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

Совместимость с файлами .Net и Mono (тестировался с Win10/ FreeBSD /CentOS)

Используя ComputerInfo исходный код и PerformanceCounters для 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)))
            };
        }
    }
}
/*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");
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top