3

I'm looking to get the value of available/free computer RAM in Swift 2.2. I've read this answer by Viktor Latypov which suggested this question. Unfortunately, the question asked about "physical memory size" (total memory i.e. 16 GB), but I am looking for "available/free memory".

I've also read about the NSProcessInfo class, but the physicalMemory() function is not what I am looking for.

Any ideas?

Community
  • 1
  • 1
perhapsmaybeharry
  • 874
  • 3
  • 13
  • 32
  • This is not a trivial thing to do. For a working example, you can examine this source code: https://github.com/beltex/SystemKit – Eric Aya Apr 27 '16 at 10:59
  • If you don't mind going down to the command line, `vm_stat` may deliver what you are looking for. Check its `man` page for details – Code Different Apr 27 '16 at 12:25
  • @Code Different I am familiar with `vm_stat`. I was rather looking for a native method of obtaining free RAM information through Swift, though `vm_stat` might be a last-resort if there is no other native method. – perhapsmaybeharry Apr 27 '16 at 12:42
  • I think you have to dive pretty deep into the Mach kernel for that. Check out [host_statistics](http://web.mit.edu/darwin/src/modules/xnu/osfmk/man/host_statistics.html) – Code Different Apr 27 '16 at 12:52

1 Answers1

3

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)!

Code Different
  • 90,614
  • 16
  • 144
  • 163