Skip to main content
Updated for 64 bit Windows systems
Source Link
Alexey Popkov
  • 62.5k
  • 7
  • 163
  • 405

The function getFreePhysMemNet[] returns the amount of free physical memory in Kb. This works both under 32bit and 64 bit Windows butmethod is 30 times slower than direct calling of the GlobalMemoryStatusEx function of kernel32.dll. Here which is the code foravailiable both on 32 bit and 64 bit Windows systems (checked under Windows 7 x64). Here is the code:

Needs["NETLink`"]; getFreePhysMem::internalError = "globalMemoryStatusEx[memorystatusex] has not returned True."; If[$OperatingSystem === "Windows" && $SystemWordLength === 32, memorystatusex = Symbol["LoadedNETTypes"][]; globalMemoryStatusEx = Symbol["DefineDLLFunction"][ "[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)] public 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( MEMORYSTATUSEX ));}} [return: MarshalAs(UnmanagedType.Bool)] [DllImport(\"kernel32.dll\", CharSet=CharSet.Auto, \ SetLastError=true)] public static extern bool GlobalMemoryStatusEx([In, Out] \ MEMORYSTATUSEX lpBuffer);"]; memorystatusex = Complement[Symbol["LoadedNETTypes"][], memorystatusex][[1, 1]]; memorystatusex = memorystatusex <> "+MEMORYSTATUSEX"; memorystatusex = Symbol["NETNew"][memorystatusex]; getFreePhysMem[] := If[TrueQ[globalMemoryStatusEx[memorystatusex]], memorystatusex@ullAvailPhys, Message[getFreePhysMem::internalError]; Abort[]; $Failed]];$OperatingSystem === "Windows", memorystatusex = Symbol["LoadedNETTypes"][]; globalMemoryStatusEx = Symbol["DefineDLLFunction"][ "[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)] public 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( MEMORYSTATUSEX ));}} [return: MarshalAs(UnmanagedType.Bool)] [DllImport(\"kernel32.dll\", CharSet=CharSet.Auto, \ SetLastError=true)] public static extern bool GlobalMemoryStatusEx([In, Out] \ MEMORYSTATUSEX lpBuffer);"]; memorystatusex = Complement[Symbol["LoadedNETTypes"][], memorystatusex][[1, 1]]; memorystatusex = memorystatusex <> "+MEMORYSTATUSEX"; memorystatusex = Symbol["NETNew"][memorystatusex]; getFreePhysMem[] := If[TrueQ[globalMemoryStatusEx[memorystatusex]], memorystatusex@ullAvailPhys, Message[getFreePhysMem::internalError]; Abort[]; $Failed]]; 

The function getFreePhysMemNet[] returns the amount of free physical memory in Kb. This works both under 32bit and 64 bit Windows but is 30 times slower than direct calling of the GlobalMemoryStatusEx function of kernel32.dll. Here is the code for 32 bit Windows systems:

Needs["NETLink`"]; getFreePhysMem::internalError = "globalMemoryStatusEx[memorystatusex] has not returned True."; If[$OperatingSystem === "Windows" && $SystemWordLength === 32, memorystatusex = Symbol["LoadedNETTypes"][]; globalMemoryStatusEx = Symbol["DefineDLLFunction"][ "[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)] public 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( MEMORYSTATUSEX ));}} [return: MarshalAs(UnmanagedType.Bool)] [DllImport(\"kernel32.dll\", CharSet=CharSet.Auto, \ SetLastError=true)] public static extern bool GlobalMemoryStatusEx([In, Out] \ MEMORYSTATUSEX lpBuffer);"]; memorystatusex = Complement[Symbol["LoadedNETTypes"][], memorystatusex][[1, 1]]; memorystatusex = memorystatusex <> "+MEMORYSTATUSEX"; memorystatusex = Symbol["NETNew"][memorystatusex]; getFreePhysMem[] := If[TrueQ[globalMemoryStatusEx[memorystatusex]], memorystatusex@ullAvailPhys, Message[getFreePhysMem::internalError]; Abort[]; $Failed]]; 

The function getFreePhysMemNet[] returns the amount of free physical memory in Kb. This method is 30 times slower than direct calling of the GlobalMemoryStatusEx function of kernel32.dll which is availiable both on 32 bit and 64 bit Windows systems (checked under Windows 7 x64). Here is the code:

Needs["NETLink`"]; getFreePhysMem::internalError = "globalMemoryStatusEx[memorystatusex] has not returned True."; If[$OperatingSystem === "Windows", memorystatusex = Symbol["LoadedNETTypes"][]; globalMemoryStatusEx = Symbol["DefineDLLFunction"][ "[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)] public 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( MEMORYSTATUSEX ));}} [return: MarshalAs(UnmanagedType.Bool)] [DllImport(\"kernel32.dll\", CharSet=CharSet.Auto, \ SetLastError=true)] public static extern bool GlobalMemoryStatusEx([In, Out] \ MEMORYSTATUSEX lpBuffer);"]; memorystatusex = Complement[Symbol["LoadedNETTypes"][], memorystatusex][[1, 1]]; memorystatusex = memorystatusex <> "+MEMORYSTATUSEX"; memorystatusex = Symbol["NETNew"][memorystatusex]; getFreePhysMem[] := If[TrueQ[globalMemoryStatusEx[memorystatusex]], memorystatusex@ullAvailPhys, Message[getFreePhysMem::internalError]; Abort[]; $Failed]]; 
Source Link
Alexey Popkov
  • 62.5k
  • 7
  • 163
  • 405

Under Windows you can use NETLink for this (it requires Microsoft .NET v.2 or later to be installed). Two methods were discussed in this MathGroups thread: "Calling kernel.dll from Mathematica. 1", "Calling kernel.dll from Mathematica. 2".

One way is to get this information via a managed API (that is, in .NET itself):

Needs["NETLink`"] query = NETNew["System.Management.ManagementObjectSearcher", "SELECT * FROM Win32_OperatingSystem"]; resultCollection = query@Get[]; mo = First[NETObjectToExpression[resultCollection]]; getFreePhysMemNet[] := (mo@Get[]; mo["FreePhysicalMemory"]) 

The function getFreePhysMemNet[] returns the amount of free physical memory in Kb. This works both under 32bit and 64 bit Windows but is 30 times slower than direct calling of the GlobalMemoryStatusEx function of kernel32.dll. Here is the code for 32 bit Windows systems:

Needs["NETLink`"]; getFreePhysMem::internalError = "globalMemoryStatusEx[memorystatusex] has not returned True."; If[$OperatingSystem === "Windows" && $SystemWordLength === 32, memorystatusex = Symbol["LoadedNETTypes"][]; globalMemoryStatusEx = Symbol["DefineDLLFunction"][ "[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)] public 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( MEMORYSTATUSEX ));}} [return: MarshalAs(UnmanagedType.Bool)] [DllImport(\"kernel32.dll\", CharSet=CharSet.Auto, \ SetLastError=true)] public static extern bool GlobalMemoryStatusEx([In, Out] \ MEMORYSTATUSEX lpBuffer);"]; memorystatusex = Complement[Symbol["LoadedNETTypes"][], memorystatusex][[1, 1]]; memorystatusex = memorystatusex <> "+MEMORYSTATUSEX"; memorystatusex = Symbol["NETNew"][memorystatusex]; getFreePhysMem[] := If[TrueQ[globalMemoryStatusEx[memorystatusex]], memorystatusex@ullAvailPhys, Message[getFreePhysMem::internalError]; Abort[]; $Failed]]; 

The function getFreePhysMem[] returns the amount of free physical memory in bytes.

Timings:

In[10]:= Do[getFreePhysMemNet[], {100}] // AbsoluteTiming Do[getFreePhysMem[], {100}] // AbsoluteTiming %%/% Out[10]= {1.9218750, Null} Out[11]= {0.0625000, Null} Out[12]= {30.7500, 1}