After spending too much on this, I couldn't go any further, so I'm putting what I have so far up here in the hope that someone can help improve it.
You can get results similar to vm_stat
on the command line with host_statistics
:
func vw_page_size() -> (kern_return_t, vm_size_t) {
var pageSize: vm_size_t = 0
let result = withUnsafeMutablePointer(&pageSize) { (size) -> kern_return_t in
host_page_size(mach_host_self(), size)
}
return (result, pageSize)
}
func vm_stat() -> (kern_return_t, vm_statistics) {
var vmstat = vm_statistics()
var count = UInt32(sizeof(vm_statistics) / sizeof(integer_t))
let result = withUnsafeMutablePointers(&vmstat, &count) { (stat, count) -> kern_return_t in
host_statistics(mach_host_self(), HOST_VM_INFO, host_info_t(stat), count)
}
return (result, vmstat)
}
let (result1, pageSize) = vw_page_size()
let (result2, vmstat) = vm_stat()
guard result1 == KERN_SUCCESS else {
fatalError("Cannot get VM page size")
}
guard result2 == KERN_SUCCESS else {
fatalError("Cannot get VM stats")
}
let total = (UInt(vmstat.free_count + vmstat.active_count + vmstat.inactive_count + vmstat.speculative_count + vmstat.wire_count) * pageSize) >> 30
let free = (UInt(vmstat.free_count) * pageSize) >> 20
print("total: \(total)GB")
print("free : \(free)MB")
The total memory tallied to less than what NSProcessInfo
returns. On my Mac with 16GB of memory, the total returned was about 15.6GB.
Calculating free memory is more problematic: there are lots of inactive and purgeable pages, but Mac OS X doesn't like to purge them until there's no more free page. So while it appears that I have only 450MB available, there are a lot more that I can use if an app needs it. And don't forget about memory compression, available since Mavericks (10.9)!