Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

Is there any way in Mathematica to find out the currently free memory on the system Mathematica runs on (like the utility free shows on the command line)? I've found out functions to show the memory occupied by Mathematica itself, but of course there are also other programs running on the system, taking their share of memory, so that number is not sufficient to estimate the free memory.

The background is that currently if I do something which might fill up my memory (and I don't forget to do it), I call free by hand, subtract a safety margin, and then use MemoryConstrained in order to prevent the memory to get completely filled up (with quite unpleasant consequences). I'd like to automate that. While I certainly could call free from Mathematica and parse its output for the number, I'd like to avoid that if I can (who knows if the next system update makes subtle changes to free and then the parsing fails to give the correct number).

share|improve this question
1  
this seems os-specific. maybe tag it as such if it is –  acl Jan 18 '12 at 14:59
    
Well, MemoryInUse[] is the polar opposite of free, I'd say... –  J. M. Jan 18 '12 at 15:00
1  
@acl: Well, the concept of free memory is certainly not OS specific. The free utility is, but I'm after a Mathematica function (if it exists) which most likely wouldn't be (I don't think there is any OS Mathematica runs on where you cannot get an estimate of available memory). Of course, if none exists, my workaround (parsing output of free) would be OS specific, but that's not what I asked for (although if someone wants to write it for me, I wouldn't complain :-)). So the OS-independent answer would be either "The function is called so-and-so and used like this" or "There isn't any." –  celtschk Jan 18 '12 at 15:08
    
@R.M: I'd not expect Mathematica to add memory of all processes (I strongly doubt free does that either). I think that every OS will have some functionality to estimate free memory (guarantees cannot be given anyway because right after returning, another process might allocate memory), and I'd expect Mathematica to use that functionality. –  celtschk Jan 18 '12 at 15:11
1  
fair enough. I doubt there is an OS-independent way of doing it, though. –  acl Jan 18 '12 at 15:19
show 3 more comments

4 Answers 4

up vote 19 down vote accepted

You might be able to use JLink along with some undocumented behaviour of the Java class java.lang.management.ManagementFactory to get the information you seek:

Needs["JLink`"]
InstallJava[];
LoadJavaClass["java.lang.management.ManagementFactory"];
JavaBlock[
  {#, java`lang`management`ManagementFactory`getOperatingSystemMXBean[]@#[]} & /@
  { getName
  , getArch
  , getVersion
  , getCommittedVirtualMemorySize
  , getFreePhysicalMemorySize
  , getFreeSwapSpaceSize
  , getTotalPhysicalMemorySize
  , getTotalSwapSpaceSize
  , getProcessCpuTime
  , getAvailableProcessors
  , getSystemLoadAverage
  } // Grid
]

This works on Windows 7 (Mathematica 8, 64-bit):

Out[368]= getName                        Windows Vista
          getArch                        amd64
          getVersion                     6.1
          getCommittedVirtualMemorySize  102449152
          getFreePhysicalMemorySize      5997510656
          getFreeSwapSpaceSize           14498115584
          getTotalPhysicalMemorySize     8587284480
          getTotalSwapSpaceSize          17172676608
          getProcessCpuTime              6068438900
          getAvailableProcessors         4
          getSystemLoadAverage           -1.

I don't have Mac or Linux boxes to hand at the moment to test whether it works there as well.

share|improve this answer
1  
it works fine on OS X (your system is not only not being loaded, but in fact actively doing negative work???) –  acl Jan 21 '12 at 20:18
4  
@acl Thanks for checking OS X. As for the negative work, everybody complains about the heat death of the universe but few do anything about it ;) –  WReach Jan 21 '12 at 20:28
1  
Do you know why this shows Windows Vista and amd64? –  Mr.Wizard Jan 22 '12 at 7:41
2  
@Mr.Wizard Windows 7 is a really just a marketing label slapped on a Vista release. It would seem that the name change happened too late to change it in the deepest parts of the OS. "amd64" is the name given to the original 64-bit instructions added to the x86 architecture. The name has stuck, although the term "x86-64" is sometimes used as a vendor-neutral term. It so happens that this workstation has an Intel CPU, not an AMD one, but the historical term is used nonetheless. –  WReach Jan 22 '12 at 16:31
1  
I've just checked on Linux, it works there as well. Moreover, the output is a Grid instead of simply a string, thus parsing isn't necessary either. I've changed the accepted answer to yours. –  celtschk Jan 22 '12 at 20:58
show 4 more comments

On Windows with an external call:

ReadList["!typeperf \"\\Memory\\Available Bytes\" -sc 1", Word, 
   RecordLists -> True, WordSeparators -> {","}] // ToExpression@Part[#,2,2]&
share|improve this answer
    
+1. Great! But it does not work for localized versions of Windows: words "Memory" and "Available Bytes" are localized and English version does not work. For getting localized names one can use the typeperf -qx command. –  Alexey Popkov Aug 19 '12 at 14:29
add comment

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 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]];

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}
share|improve this answer
add comment

Since Mathematica runs on only a few different OS's, why not write a little conditional expression that, for each OS, feeds to a shell the corresponding command that returns the amount of free memory.

The trouble, of course, is that not all OS's are equal in this regard. I don't know of a Mac OS X built-in command equivalent to the Linux free, but you can locate Python scripts that will do the equivalent thing.

share|improve this answer
    
Given that until now nobody has told me one, I have to conclude that there's indeed no ready-made Mathematica function (or if there is, it's so hidden in undocumented internals that nobody knows about it), therefore I accept your answer as the right one. –  celtschk Jan 19 '12 at 5:58
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.