9

I need to retrieve the total amount of RAM present in a system and the total RAM currently being used, so I can calculate a percentage. This is similar to: Retrieve system information on MacOS X?

However, in that question the best answer suggests how to get RAM by reading from:

/usr/bin/vm_stat

Due to the nature of my program, I found out that I am not cannot read from that file - I require a method that will provide me RAM info without simply opening a file and reading from it. I am looking for something to do with function calls. Something like this preferably : getTotalRam() and getRamInUse().

I obviously do not expect it to be that simple but I was looking for a solution other than reading from a file.

I am running Mac OS X Snow Leopard, but would preferably get a solution that would work across all current Mac OS X Platforms (i.e. Lion).

Solutions can be in C++, C or Obj-C, however C++ would the best possible solution in my case so if possible please try to provide it in C++.

Community
  • 1
  • 1
fdh
  • 5,256
  • 13
  • 58
  • 101

4 Answers4

15

Getting the machine's physical memory is simple with sysctl:

int mib [] = { CTL_HW, HW_MEMSIZE };
int64_t value = 0;
size_t length = sizeof(value);

if(-1 == sysctl(mib, 2, &value, &length, NULL, 0))
    // An error occurred

// Physical memory is now in value

VM stats are only slightly trickier:

mach_msg_type_number_t count = HOST_VM_INFO_COUNT;
vm_statistics_data_t vmstat;
if(KERN_SUCCESS != host_statistics(mach_host_self(), HOST_VM_INFO, (host_info_t)&vmstat, &count))
    // An error occurred

You can then use the data in vmstat to get the information you'd like:

double total = vmstat.wire_count + vmstat.active_count + vmstat.inactive_count + vmstat.free_count;
double wired = vmstat.wire_count / total;
double active = vmstat.active_count / total;
double inactive = vmstat.inactive_count / total;
double free = vmstat.free_count / total;

There is also a 64-bit version of the interface.

sbooth
  • 16,646
  • 2
  • 55
  • 81
  • Thanks. Just one question: What's the difference between physical memory and VM? – fdh Jan 09 '12 at 01:31
  • @Farhad: In this context, virtual memory also includes the parts of processes paged out to disk. (It's also addressed differently). – MSalters Jan 09 '12 at 09:42
  • Is there a way I can check only the physical RAM being used? (I don't want disk swaps included) sysctl provides the total RAM but not the amount being actually used. – fdh Jan 09 '12 at 14:19
7

You're not supposed to read from /usr/bin/vm_stat, rather you're supposed to run it; it is a program. Look at the first four lines of output

Pages free:                  1880145.
Pages active:                  49962.
Pages inactive:                43609.
Pages wired down:             123353.

Add the numbers in the right column and multiple by the system page size (as returned by getpagesize()) and you get the total amount of physical memory in the system in bytes.

vm_stat isn't setuid on Mac OS, so I assume there is a non-privileged API somewhere to access this information and that vm_stat is using it. But I don't know what that interface is.

Kyle Jones
  • 5,492
  • 1
  • 21
  • 30
  • Thanks, that gets me the total ram in the system but how would I get the total ram being used right now? – fdh Jan 08 '12 at 23:31
  • @Fahrhad - that's what active, inactive, & wired pages are. Well, depending on your definition of 'used'. – Carl Norum Jan 08 '12 at 23:34
  • @CarlNorum Sorry I'm not really familiar with all of this. What is normally considered "used RAM"? Is it only active and wired or does it include inactive pages too? – fdh Jan 09 '12 at 00:09
  • And also one more thing. Isn't this virtual memory as opposed to RAM? From what I understand RAM is the memory while virtual memory is storage used as memory, so does this return RAM or virtual memory? (considering the fact that the name IS virtual memory_stat) – fdh Jan 09 '12 at 00:13
  • @Farhad Those numbers refer to physical memory, not virtual. Perhaps [this support page from Apple](http://support.apple.com/kb/ht1342) will help you. It tells what each number means. – Kyle Jones Jan 09 '12 at 18:52
5

You can figure out the answer to this question by looking at the source of the top command. You can download the source from http://opensource.apple.com/. The 10.7.2 source is available as an archive here or in browsable form here. I recommend downloading the archive and opening top.xcodeproj so you can use Xcode to find definitions (command-clicking in Xcode is very useful).

The top command displays physical memory (RAM) numbers after the label "PhysMem". Searching the project for that string, we find it in the function update_physmem in globalstats.c. It computes the used and free memory numbers from the vm_stat member of struct libtop_tsamp_t.

You can command-click on "vm_stat" to find its declaration as a membor of libtop_tsamp_t in libtop.h. It is declared as type vm_statistics_data_t. Command-clicking that jumps to its definition in /usr/include/mach/vm_statistics.h.

Searching the project for "vm_stat", we find that it is filled in by function libtop_tsamp_update_vm_stats in libtop.c:

mach_msg_type_number_t count = sizeof(tsamp->vm_stat) / sizeof(natural_t);
kr = host_statistics(libtop_port, HOST_VM_INFO, (host_info_t)&tsamp->vm_stat, &count);
if (kr != KERN_SUCCESS) {
    return kr;
}

You will need to figure out how libtop_port is set if you want to call host_statistics. I'm sure you can figure that out for yourself.

rob mayoff
  • 375,296
  • 67
  • 796
  • 848
3

It's been 4 years but I just wanted to add some extra info on calculating total RAM.

To get the total RAM, we should also consider Pages occupied by compressor and Pages speculative in addition to Kyle Jones answer.

You can check out this post for where the problem occurs.

Community
  • 1
  • 1