Getting memory usage Live/Dirty Bytes in iOS app programmatically (not Resident/Real Bytes)

我们两清 提交于 2019-12-08 00:25:17

问题


According to what I've read so far, real/resident bytes indicates the number of bytes allocated to the app including bytes that the app is no longer using but hasn't been reclaimed by the OS. And live/dirty bytes is the bytes the the app is actually using and the OS can't reclaim. I think that the number shown in XCode Debug navigator is Live Bytes.

I'm interested in getting this number programmatically (for our own statistics/analytics), but the code I found can only give the value of resident bytes, which is larger than the value that Xcode is showing on some devices (almost twice is large), actually on the same devices but different iOS versions. (on iOS 9 it gives a value almost twice as large but on iOS 11 it gives almost the same value as Xcode).

The code I am using is this:

struct mach_task_basic_info info;
mach_msg_type_number_t size = MACH_TASK_BASIC_INFO_COUNT;
kern_return_t kerr = task_info(mach_task_self(),
                               MACH_TASK_BASIC_INFO,
                               (task_info_t)&info,
                               &size);
if( kerr == KERN_SUCCESS ) {
    NSLog(@"Memory in use (in bytes): %u", info.resident_size);
    return info.resident_size;
} else {
    NSLog(@"Error with task_info(): %s", mach_error_string(kerr));
}

Is there some code to get the live bytes value like Xcode shows?


回答1:


I found something else, but it seems to work on the device that the previous method didn't work and not work on the device that the previous method did work :-( Now I need to figure out how to know which one to use. One device is iPhone 5s with iOS 9 and another is iPhone 5s with iOS 11. I guess I need to test on more veriaty of devices...

I found it here:

https://opensource.apple.com/source/WebKit/WebKit-7603.1.30.1.33/ios/Misc/MemoryMeasure.mm.auto.html

This translated to something like this in Objective-C:

task_vm_info_data_t vmInfo;
mach_msg_type_number_t count = TASK_VM_INFO_COUNT;
kern_return_t err = task_info(mach_task_self(), TASK_VM_INFO, (task_info_t) &vmInfo, &count);
if (err != KERN_SUCCESS)
    return 0;

NSLog(@"Memory in use vmInfo.internal (in bytes): %u", vmInfo.internal);

return vmInfo.internal;

I think if I add vmInfo.internal and vmInfo.compressed then I'll get the right result (matching what Xcode Debug navigator is showing)

It looks right for these two devices so far, and 2 other devices I tested.

So my final code looks like this:

task_vm_info_data_t info;
mach_msg_type_number_t size = TASK_VM_INFO_COUNT;
kern_return_t kerr = task_info(mach_task_self(),
                               TASK_VM_INFO,
                               (task_info_t)&info,
                               &size);
if( kerr == KERN_SUCCESS ) {
    mach_vm_size_t totalSize = info.internal + info.compressed;
    NSLog(@"Memory in use (in bytes): %u", totalSize);
    return totalSize;
} else {
    NSLog(@"Error with task_info(): %s", mach_error_string(kerr));
}



回答2:


Since access to Darwin types looks slightly different in Obj-C and Swift I wanted to add the solution I came up in Swift based on Alex's answer:

let TASK_VM_INFO_COUNT = MemoryLayout<task_vm_info_data_t>.size / MemoryLayout<natural_t>.size

var vmInfo = task_vm_info_data_t()
var vmInfoSize = mach_msg_type_number_t(TASK_VM_INFO_COUNT)

let kern: kern_return_t = withUnsafeMutablePointer(to: &vmInfo) {
        $0.withMemoryRebound(to: integer_t.self, capacity: 1) {
            task_info(mach_task_self_,
                      task_flavor_t(TASK_VM_INFO),
                      $0,
                      &vmInfoSize)
            }
        }

if kern == KERN_SUCCESS {
    let usedSize = DataSize(bytes: Int(vmInfo.internal + vmInfo.compressed))
    print("Memory in use (in bytes): %u", usedSize)
} else {
    let errorString = String(cString: mach_error_string(kern), encoding: .ascii) ?? "unknown error"
    print("Error with task_info(): %s", errorString);
}

This code is based on similar answer with mach_task_basic_info and resident_size.



来源:https://stackoverflow.com/questions/48990831/getting-memory-usage-live-dirty-bytes-in-ios-app-programmatically-not-resident

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!