كيف يمكنك الحصول على إجمالي حجم ذاكرة الوصول العشوائي (RAM) الموجودة بالكمبيوتر؟

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

  •  01-07-2019
  •  | 
  •  

سؤال

باستخدام C#، أريد الحصول على إجمالي حجم ذاكرة الوصول العشوائي (RAM) الموجودة بجهاز الكمبيوتر الخاص بي.باستخدام PerformanceCounter يمكنني الحصول على مقدار ذاكرة الوصول العشوائي المتوفرة، وذلك عن طريق الإعداد:

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

لكن لا يمكنني العثور على طريقة للحصول على الحجم الإجمالي للذاكرة.كيف لي أن تذهب عن القيام بذلك؟

تحديث:

ماجيك كات:لقد رأيت ذلك عندما كنت أبحث، لكنه لا يعمل - "هل تفتقد تجميعًا أو مرجعًا؟".لقد بحثت لإضافة ذلك إلى المراجع، ولكن لا أرى ذلك هناك.

هل كانت مفيدة؟

المحلول

طريقة ع/استدعاء يحرر :تم التغيير إلى 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);

ثم استخدم مثل:

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

إذا كنت مهتمًا برمز C الذي يوفر عداد الأداء، فيمكنك العثور عليه هنا.

جميع الإجابات هنا، بما في ذلك الإجابات المقبولة، ستمنحك إجمالي حجم ذاكرة الوصول العشوائي متاح للاستخدام.وربما كان هذا هو ما أراده OP.

ولكن إذا كنت مهتمًا بالحصول على المبلغ المثبتة RAM، فسوف ترغب في إجراء مكالمة إلى احصل على ذاكرة النظام المثبتة فعليًا وظيفة.

من الرابط في قسم الملاحظات :

ال احصل على ذاكرة النظام المثبتة فعليًا تسترد الوظيفة مقدار ذاكرة الوصول العشوائي (RAM) المثبتة فعليًا من جداول البرامج الثابتة SMBIOS للكمبيوتر.يمكن أن يختلف هذا عن المبلغ الذي أبلغت عنه حالة الذاكرة العالميةEx الوظيفة، التي تقوم بتعيين عضو ullTotalPhys في بنية 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"))));

لم يذكر أحد احصل على معلومات الأداء حتى الآن. استدعاء التوقيعات تتوفر.

تتيح هذه الوظيفة المعلومات التالية على مستوى النظام:

  • إجمالي الالتزام
  • CommitLimit
  • قمة الالتزام
  • المجموع المادي
  • المادية المتاحة
  • SystemCache
  • KernelTotal
  • KernelPaged
  • KernelNopaged
  • مقاس الصفحه
  • HandleCount
  • عدد العمليات
  • عدد الصفحات

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