Contact US

Log In

Come Join Us!

Are you a
Computer / IT professional?
Join Tek-Tips Forums!
  • Talk With Other Members
  • Be Notified Of Responses
    To Your Posts
  • Keyword Search
  • One-Click Access To Your
    Favorite Forums
  • Automated Signatures
    On Your Posts
  • Best Of All, It's Free!

*Tek-Tips's functionality depends on members receiving e-mail. By joining you are opting in to receive e-mail.

Posting Guidelines

Promoting, selling, recruiting, coursework and thesis posting is forbidden.

Students Click Here

System Information

How do I determine the amount of RAM? by Griffyn
Posted: 19 Sep 09 (Edited 4 Dec 09)

It's become more difficult to determine the amount of RAM in a system, since >2GB became more common, and some operating systems don't handle reporting of more than 2GB correctly.  The following code should handle any combination of OS and RAM amount.


// for automatic syntax highlighting see FAQ102-6487: How to include syntax highlighting in code examples.
  TMemoryStatusEx = record
    dwLength: DWORD;
    dwMemoryLoad: DWORD;
    ullTotalPhys: Int64;
    ullAvailPhys: Int64;
    ullTotalPageFile: Int64;
    ullAvailPageFile: Int64;
    ullTotalVirtual: Int64;
    ullAvailVirtual: Int64;
    ullAvailExtendedVirtual: Int64;

function GetGlobalMemoryRecord: TMemoryStatusEx;
  TGlobalMemoryStatusEx = procedure(var lpBuffer: TMemoryStatusEx); stdcall;
  ms : TMemoryStatus;
  h : THandle;
  gms : TGlobalMemoryStatusEx;
  Result.dwLength := SizeOf(Result);
  h := LoadLibrary(kernel32);
    if h <> 0 then
      @gms := GetProcAddress(h, 'GlobalMemoryStatusEx');
      if @gms <> nil then
        ms.dwLength := SizeOf(ms);
        Result.dwMemoryLoad := ms.dwMemoryLoad;
        Result.ullTotalPhys := ms.dwTotalPhys;
        Result.ullAvailPhys := ms.dwAvailPhys;
        Result.ullTotalPageFile := ms.dwTotalPageFile;
        Result.ullAvailPageFile := ms.dwAvailPageFile;
        Result.ullTotalVirtual := ms.dwTotalVirtual;
        Result.ullAvailVirtual := ms.dwAvailVirtual;

function GetTotalRAM: Int64;
  Result := GetGlobalMemoryRecord.ullTotalPhys;

You can see from the record structure it is trivial to get other values from the system.

To ensure accurate reporting for systems that have between 2GB and 4GB of RAM, the /LARGEADDRESSAWARE flag must be set in the compiled .EXE.  Delphi 6 and earlier don't have this as an option in the IDE, so you must include this line


{$SetPEFlags $0020}   { /LargeAddressAware }
in your .dpr (project source) file.  Putting it in a unit, such as your main form unit is not enough as the linker will not include it unless the unit is recompiled.

I'm not sure if this option is included in D7 or above.  Setting that option in the linker options if it's available should be enough.

One last code snippet to format the byte count to something more readable:


{ This function returns a formatted string with at the appropriate level of bytes, kilobytes, megabytes, gigabytes, etc }
function FormatBytes(ABytes: Int64; AShortRounding: Boolean = True): String;
  suffix : array[0..6] of String = ('B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB');
  l : Integer;
  f : Double;
  l := 0;
  f := ABytes;
  while (l < High(suffix)) and (f >= 1024) do
    f := f / 1024;
  if AShortRounding and (l < High(suffix)) and (f >= 1000) then
  begin    // ensures eg. 1022 MB will show 0.99 GB
    f := f / 1024;
  Result := Format('%f %s', [f, suffix[l]]);

Back to Embarcadero: Delphi FAQ Index
Back to Embarcadero: Delphi Forum

My Archive

Close Box

Join Tek-Tips® Today!

Join your peers on the Internet's largest technical computer professional community.
It's easy to join and it's free.

Here's Why Members Love Tek-Tips Forums:

Register now while it's still free!

Already a member? Close this window and log in.

Join Us             Close