iOS 獲取APP的CPU、內(nèi)存等信息

http://stackoverflow.com/questions/12889422/ios-cpu-usage-for-each-process-using-sysctl

采用的是sysctl函數(shù),但是出來(lái)的CPU數(shù)據(jù)和instrument、GT的數(shù)據(jù)對(duì)不上(后兩者數(shù)據(jù)比較接近)

https://github.com/TianJIANG/ios_monitor

利用的主要是#import <mach/mach.h> 里面的task_info 等,打開(kāi)了一道新的大門(mén),后續(xù)找到不少類(lèi)似的方法

http://stackoverflow.com/questions/8223348/ios-get-cpu-usage-from-application

這個(gè)答案也是給的這個(gè)方法,末尾額外加了一行代碼, vm_dealloc,解決leaking問(wèn)題

補(bǔ)充幾個(gè)相關(guān)的:

http://stackoverflow.com/questions/5182924/where-is-my-ipad-runtime-memory-going%E2%80%8C%E2%80%8B

http://blog.sina.com.cn/s/blog_693de6100101ffwm.html

http://www.zhihu.com/question/22992491

Github 搜 “Activity Monitor”

https://github.com/AndrewBarba/ActivityMonitor

https://github.com/vsnrain/ActivityMonitor

此算法是獲取當(dāng)前APP的CPU,數(shù)值與Instrument、GT接近


- (void)GetCpuUsage {

    kern_return_t kr;

    task_info_data_t tinfo;

    mach_msg_type_number_t task_info_count;

    task_info_count = TASK_INFO_MAX;

    kr = task_info(mach_task_self(), TASK_BASIC_INFO, (task_info_t)tinfo, &task_info_count);

    if(kr != KERN_SUCCESS) {

        return;

    }

    task_basic_info_t      basic_info;

    thread_array_t        thread_list;

    mach_msg_type_number_t thread_count;

    thread_info_data_t    thinfo;

    mach_msg_type_number_t thread_info_count;

    thread_basic_info_t basic_info_th;

    uint32_t stat_thread =0;// Mach threads   

    basic_info = (task_basic_info_t)tinfo;

    // get threads in the taskkr = task_threads(mach_task_self(), &thread_list, &thread_count);

    if(kr != KERN_SUCCESS) {

        return;

    }

    if(thread_count >0)

        stat_thread += thread_count;

    longtot_sec =0;

    longtot_usec =0;

    floattot_cpu =0;

    int j;

    for(j =0; j < thread_count; j++)

    {

        thread_info_count = THREAD_INFO_MAX;

        kr = thread_info(thread_list[j], THREAD_BASIC_INFO,

                        (thread_info_t)thinfo, &thread_info_count);

        if(kr != KERN_SUCCESS) {

            return;

        }

        basic_info_th = (thread_basic_info_t)thinfo;

        if(!(basic_info_th->flags & TH_FLAGS_IDLE)) {

            tot_sec = tot_sec + basic_info_th->user_time.seconds + basic_info_th->system_time.seconds;

            tot_usec = tot_usec + basic_info_th->system_time.microseconds + basic_info_th->system_time.microseconds;

            tot_cpu = tot_cpu + basic_info_th->cpu_usage / (float)TH_USAGE_SCALE *100.0;

        }

    } // for each thread   

    kr = vm_deallocate(mach_task_self(), (vm_offset_t)thread_list, thread_count *sizeof(thread_t));

    assert(kr == KERN_SUCCESS);

    NSLog(@"CPU Usage: %f \n", tot_cpu);

}

此算法是獲取當(dāng)前APP的內(nèi)存,數(shù)值與GT的一致,與Instrument不一致


- (void)GetCurrentTaskUsedMemory {

    task_basic_info_data_t taskInfo;

    mach_msg_type_number_t infoCount = TASK_BASIC_INFO_COUNT;

    kern_return_t kernReturn = task_info(mach_task_self(),

                                        TASK_BASIC_INFO, (task_info_t)&taskInfo, &infoCount);

    if(kernReturn != KERN_SUCCESS) {

        return;

    }

    NSLog(@"Memory Usage: %f", taskInfo.resident_size /1024.0/1024.0);

}

XNU

https://en.wikipedia.org/wiki/XNU

MACH

https://en.wikipedia.org/wiki/Mach_(kernel)

Kernel Programming Guide

https://developer.apple.com/library/mac/documentation/Darwin/Conceptual/KernelProgramming/About/About.html

github 上搜 mach_msg_type_number_t

https://github.com/search?l=objective-c&q=mach_msg_type_number_t&type=Code&utf8=?

用VM Tracker查看內(nèi)存,有那么幾項(xiàng)

Resident Size|Dirty Size|Virtual Size

http://stackoverflow.com/questions/5176074/what-do-dirty-and-resident-mean-in-relation-to-virtual-memory

這篇解釋了三者的差別,我理解我們應(yīng)該跟蹤的是Resident Size,但是數(shù)值上與VM Tracker上對(duì)不上


- (void)GetMemoryStatistics {

    // Get Page Sizeintmib[2];

    int page_size;

    size_t len;

    mib[0] = CTL_HW;

    mib[1] = HW_PAGESIZE;

    len =sizeof(page_size);

    //// 方法一: 16384//    int status = sysctl(mib, 2, &page_size, &len, NULL, 0);//    if (status < 0) {//        perror("Failed to get page size");//    }//// 方法二: 16384//    page_size = getpagesize();

    // 方法三: 4096if( host_page_size(mach_host_self(), &page_size)!= KERN_SUCCESS ){

        perror("Failed to get page size");

    }

    printf("Page size is %d bytes\n", page_size);

    // Get Memory Sizemib[0] = CTL_HW;

    mib[1] = HW_MEMSIZE;

    long ram;

    len =sizeof(ram);

    if(sysctl(mib,2, &ram, &len, NULL,0)) {

        perror("Failed to get ram size");

    }

    printf("Ram size is %f MB\n", ram / (1024.0) / (1024.0));

    // Get Memory Statistics//    vm_statistics_data_t vm_stats;//    mach_msg_type_number_t info_count = HOST_VM_INFO_COUNT;    vm_statistics64_data_t vm_stats;

    mach_msg_type_number_t info_count64 = HOST_VM_INFO64_COUNT;//    kern_return_t kern_return = host_statistics(mach_host_self(), HOST_VM_INFO, (host_info_t)&vm_stats, &info_count);kern_return_t kern_return = host_statistics64(mach_host_self(), HOST_VM_INFO64, (host_info64_t)&vm_stats, &info_count64);

    if(kern_return != KERN_SUCCESS) {

        printf("Failed to get VM statistics!");

    }

    doublevm_total = vm_stats.wire_count + vm_stats.active_count + vm_stats.inactive_count + vm_stats.free_count;

    doublevm_wire = vm_stats.wire_count;

    doublevm_active = vm_stats.active_count;

    doublevm_inactive = vm_stats.inactive_count;

    doublevm_free = vm_stats.free_count;

    doubleunit = (1024.0) * (1024.0);

    NSLog(@"Total Memory: %f", vm_total * page_size / unit);

    NSLog(@"Wired Memory: %f", vm_wire * page_size / unit);

    NSLog(@"Active Memory: %f", vm_active * page_size / unit);

    NSLog(@"Inactive Memory: %f", vm_inactive * page_size / unit);

    NSLog(@"Free Memory: %f", vm_free * page_size / unit);

}

1、關(guān)于Ram大小,用HW_MEMSIZE計(jì)算得到1000MB,是準(zhǔn)確的

2、關(guān)于page size,上面提供了三種方法

其中方法一、二在64位機(jī)器上返回了16384,只有第三種方法返回了4096

http://stackoverflow.com/questions/21552747/strange-behavior-on-64bit-ios-devices-when-retrieving-vm-statistics/33574804#33574804

這篇文章提出了此疑問(wèn),但是沒(méi)有特別明確的解釋

我認(rèn)為page size應(yīng)該是4096,用VM Tracker運(yùn)行,截圖如下:

image

以第一項(xiàng)_LINKEDIT為例,13692*4096/1024/1024=53.48M,與Vitual Size吻合

3、關(guān)于vm_total、vm_wire、vm_active、vm_inactive、vm_free這幾個(gè)值

其中一組運(yùn)行結(jié)果如下:


Page sizeis4096 bytes

Ram size is1000.000000 MB2015-11-2220:59:41.191CompSDKDemo[1602:410503] Total Memory:777.5195312015-11-2220:59:41.191CompSDKDemo[1602:410503] Wired Memory:205.4843752015-11-2220:59:41.192CompSDKDemo[1602:410503] Active Memory:374.9414062015-11-2220:59:41.192CompSDKDemo[1602:410503] Inactive Memory:175.7109382015-11-2220:59:41.192CompSDKDemo[1602:410503] Free Memory:21.382812

可以看到,Total Memory不是1000MB,這個(gè)如何解釋呢?

a. 1000M應(yīng)該是實(shí)際的RAM大小,而Total Memory,應(yīng)該是Virtual Memory,兩者是否一回事,有待商榷?

b. 從APP Store上下了一個(gè)System Monitor,如下:

可以看到,Wired、Active、Inactive的值都對(duì)得上,唯獨(dú)Free的值對(duì)不上

不負(fù)責(zé)任的猜測(cè),他的Free是通過(guò)1000M減其它三項(xiàng)得到的

image

Source Code : Get Hardware Info of iPhone

http://blog.sina.com.cn/s/blog_4a04a3c90100r9gn.html

How to determine CPU and memory consumption from inside a process?

http://stackoverflow.com/questions/63166/how-to-determine-cpu-and-memory-consumption-from-inside-a-process

總結(jié)下來(lái),關(guān)于內(nèi)存的有兩個(gè)問(wèn)題:

1. active、inactive、wired、free加起來(lái)不等于1000M

這個(gè)可以先放一放,我們可以先不用管這部分

2. 當(dāng)前app消耗的內(nèi)存,目前的算法與 Debug Gauges的值有偏差,與GT吻合

不過(guò)發(fā)現(xiàn)點(diǎn)擊頁(yè)面增長(zhǎng)的值和發(fā)回釋放的值,與Debug Gauges基本一致,因此可以使用

關(guān)于CPU,上面算法給出的值符合要求,可以使用;

接下來(lái)是:耗電量、網(wǎng)速、幀率

耗電量,目前沒(méi)有找到合適的工具

有兩種獲取電池電量信息的方法

方法一:

這個(gè)方法需要導(dǎo)入 IOKit 庫(kù),但是不知從什么時(shí)候開(kāi)始,iOS系統(tǒng)不允許用戶導(dǎo)入庫(kù)

http://www.cocoachina.com/bbs/read.php?tid=268692

這篇文章提供了野路子方法,但是實(shí)施起來(lái)頗為不便,考慮到要做sdk,不適合

CFTypeRef blob = IOPSCopyPowerSourcesInfo();

CFArrayRef sources = IOPSCopyPowerSourcesList(blob);

方法二:

[UIDevice currentDevice].batteryLevel

據(jù)說(shuō)精度達(dá)到1%

找到一篇文章,提供了三種方法

iOS開(kāi)發(fā)之runtime精準(zhǔn)獲取電池電量

http://www.itdecent.cn/p/11c1afdf5415

網(wǎng)絡(luò)流量

https://github.com/QbsuranAlang/GetNetworkFlow/blob/master/GetNetworkFlow/GetNetworkFlow/ViewController.m

經(jīng)測(cè)試,mach方法獲取的內(nèi)存值與top命令拿到的RSS、VSS是一致的

原文:https://www.cnblogs.com/mobilefeng/p/4977783.html

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容