none
GlobalMemoryStatus returns negative junk value

    Question

  • Hi all,

    i am retrieving total physical memory using GlobalMemoryStatus() as follows :


    public struct MemoryStatus
    {
    public uint Length; //Length of struct
    public uint MemoryLoad; //Value from 0-100 represents memory usage
    public uint TotalPhysical;
    public uint AvailablePhysical;
    public uint TotalPageFile;
    public uint AvailablePageFile;
    public uint TotalVirtual;
    public uint AvailableVirtual;

    }
    MemoryStatus stat;

    [DllImport("kernel32.dll")]
    public static extern void GlobalMemoryStatus(out MemoryStatus stat);


    GlobalMemoryStatus(out stat);
    uint totPhy = stat.TotalPhysical;


    My question is
    1) Is the stat.TotalPhysical return the actual physical memory installed int he machine ?

    2) I am getting neagtive value like -271691776 for the vista mahcine(Os type : 6.0.6001) and Windows Server 2000 . What is the reason

    Can someone please help me out.Thanks in advance
    Monday, March 09, 2009 12:44 PM

Answers

  • Add a new class to your project and paste this code:

    using System;
    using System.ComponentModel;
    using System.Runtime.InteropServices;

    public class Utils {
      public static ulong GetPhysicalMemory() {
        MEMORYSTATUSEX status = new MEMORYSTATUSEX();
        status.length = Marshal.SizeOf(status);
        if (!GlobalMemoryStatusEx(ref status)) {
          int err = Marshal.GetLastWin32Error();
          throw new Win32Exception(err);
        }
        return status.totalPhys;
      }

      [StructLayout(LayoutKind.Sequential)]
      private struct MEMORYSTATUSEX {
        public int length;
        public int memoryLoad;
        public ulong totalPhys;
        public ulong availPhys;
        public ulong totalPageFile;
        public ulong availPageFile;
        public ulong totalVirtual;
        public ulong availVirtual;
        public ulong availExtendedVirtual;
      }
      [DllImport("kernel32.dll", SetLastError = true)]
      private static extern bool GlobalMemoryStatusEx(ref MEMORYSTATUSEX buffer);
    }

    Call it like this:

          ulong mem = Utils.GetPhysicalMemory();


    Hans Passant.
    • Marked as answer by Zhi-Xin Ye Thursday, March 12, 2009 9:30 AM
    • Unmarked as answer by Coder_Cool Friday, May 22, 2009 1:40 PM
    • Marked as answer by nobugzMVP, Moderator Wednesday, June 03, 2009 9:41 PM
    Monday, March 09, 2009 4:56 PM

All replies

  • Didn't we already tell you that you have to use GlobalMemoryStatusEx()?
    Hans Passant.
    Monday, March 09, 2009 12:52 PM
  • but how come i have got negative junk number instead of -1. that too for Vista and Windows server 2000 machine alone i have got such values
    For GlobalMemoryStatusEx() , i have seen in msdn link that "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."


    I want to get only the phyical memory installed int he machine thats actual RAM. Will this API provides me the excat value for all machines??

    because i have seen for GLobalMemoryStatus() link , " On Intel x86 computers with more than 2 GB and less than 4 GB of memory, the GlobalMemoryStatus function will always return 2 GB in the dwTotalPhys member of the MEMORYSTATUS structure"

    Can u plz explain me
    Monday, March 09, 2009 1:45 PM
  • Add a new class to your project and paste this code:

    using System;
    using System.ComponentModel;
    using System.Runtime.InteropServices;

    public class Utils {
      public static ulong GetPhysicalMemory() {
        MEMORYSTATUSEX status = new MEMORYSTATUSEX();
        status.length = Marshal.SizeOf(status);
        if (!GlobalMemoryStatusEx(ref status)) {
          int err = Marshal.GetLastWin32Error();
          throw new Win32Exception(err);
        }
        return status.totalPhys;
      }

      [StructLayout(LayoutKind.Sequential)]
      private struct MEMORYSTATUSEX {
        public int length;
        public int memoryLoad;
        public ulong totalPhys;
        public ulong availPhys;
        public ulong totalPageFile;
        public ulong availPageFile;
        public ulong totalVirtual;
        public ulong availVirtual;
        public ulong availExtendedVirtual;
      }
      [DllImport("kernel32.dll", SetLastError = true)]
      private static extern bool GlobalMemoryStatusEx(ref MEMORYSTATUSEX buffer);
    }

    Call it like this:

          ulong mem = Utils.GetPhysicalMemory();


    Hans Passant.
    • Marked as answer by Zhi-Xin Ye Thursday, March 12, 2009 9:30 AM
    • Unmarked as answer by Coder_Cool Friday, May 22, 2009 1:40 PM
    • Marked as answer by nobugzMVP, Moderator Wednesday, June 03, 2009 9:41 PM
    Monday, March 09, 2009 4:56 PM
  • Thanks Hans Passant
    Wednesday, March 11, 2009 9:23 AM
  • Hi ,
    I am always gettign error in GlobalMemoryStatusEX(ref status) call. and the err no is always 87 . Please help me to resolve this problem.
    Thanks.

    Friday, May 22, 2009 1:42 PM
  • that's because you probably didn't set the length of the field like it says in the msdn sampel..

    "

    dwLength

    The size of the structure, in bytes. You must set this member before calling GlobalMemoryStatusEx .

    "

     

    MEMORYSTATUSEX statex;

    statex.dwLength = sizeof (statex);

    GlobalMemoryStatusEx (&statex);

     

     

    Thursday, August 26, 2010 7:35 PM