Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get memory usage in Swift [duplicate]

Tags:

ios

swift

iphone

I need to get the memory usage (MB) for my app programmatically in Swift. I found sample code for Objective-C. Anyone can help me to convert this into Swift. Thanks!

void report_memory(void) {
  struct task_basic_info info;
  mach_msg_type_number_t size = sizeof(info);
  kern_return_t kerr = task_info(mach_task_self(),
                             TASK_BASIC_INFO,
                             (task_info_t)&info,
                             &size);
  if( kerr == KERN_SUCCESS ) {
    NSLog(@"Memory in use (in bytes): %u", info.resident_size);
  } else {
    NSLog(@"Error with task_info(): %s", mach_error_string(kerr));
  }
}
like image 927
BB_Dev Avatar asked Apr 22 '15 10:04

BB_Dev


1 Answers

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.

like image 147
Airspeed Velocity Avatar answered Sep 28 '22 02:09

Airspeed Velocity