How to get memory usage in Swift [duplicate]

edit: oops, should have checked for duplicates first, Nate answered this question already here. Though you might want to note the slight difference in my version, which uses withUnsafeMutablePointer.

You’re getting downvoted since people don’t like “How can I convert this Obj-C code to Swift” questions, however in this case it might be fair enough since this this specific conversion is particularly hairy. I think this is working:

func report_memory() {
    var info = task_basic_info()
    var count = mach_msg_type_number_t(sizeofValue(info))/4

    let kerr: kern_return_t = withUnsafeMutablePointer(&info) {

        task_info(mach_task_self_,
            task_flavor_t(TASK_BASIC_INFO),
            task_info_t($0),
            &count)

    }

    if kerr == KERN_SUCCESS {
        println("Memory in use (in bytes): \(info.resident_size)")
    }
    else {
        println("Error with task_info(): " +
            (String.fromCString(mach_error_string(kerr)) ?? "unknown error"))
    }
}

There’s a couple of basic coercions – sizeof returns an Int, but the function call needs a UInt32. Similarly (and slightly more infuriatingly), TASK_BASIC_INFO is an Int32, but the call needs a UInt32.

The nasty part is passing in the third parameter. task_info takes a pointer to multiple different kinds of structs of different sizes depending on what kind of info you want. So you need to get a pointer from your task_basic_info object, then cast it to the specific kind of pointer task_info actually wants (which is, once you wade through all the typedefs, a pointer to UInt32).

The docs for task_info say that the last count parameter is supposed to be a count of the “maximum number of integers in task_info” but when it says integers I guess it means 32-bit integers hence divide by 4.

Leave a Comment