目标是开发一个SDK,嵌入到APP里面,用来统计当前APP的实时CPU、内存等信息

2015.11.17

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

这是第一个找到,采用的是sysctl函数

但是出来的CPU数据和instrument、GT的数据对不上(后两者数据比较接近)

2015.11.19

https://github.com/TianJIANG/ios_monitor

从guithub上搜到的,利用的主要是#import <mach/mach.h> 里面的task_info 等,打开了一道新的大门,后续找到不少类似的方法

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

这个答案也是给的这个方法,末尾额外加了一行代码, vm_dealloc,解决leaking问题

补充几个相关的:

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

此算法是获取当前APP的CPU,数值与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 = ; // Mach threads basic_info = (task_basic_info_t)tinfo; // get threads in the task
kr = task_threads(mach_task_self(), &thread_list, &thread_count);
if (kr != KERN_SUCCESS) {
return;
}
if (thread_count > )
stat_thread += thread_count; long tot_sec = ;
long tot_usec = ;
float tot_cpu = ;
int j; for (j = ; 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);
}

此算法是获取当前APP的内存,数值与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);
}

2015.11.20

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=✓

2015.11.22

用VM Tracker查看内存,有那么几项

Resident Size|Dirty Size|Virtual Size

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

这篇解释了三者的差别,我理解我们应该跟踪的是Resident Size,但是数值上与VM Tracker上对不上

- (void)GetMemoryStatistics {

    // Get Page Size
int mib[];
int page_size;
size_t len; mib[] = CTL_HW;
mib[] = 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();
// 方法三: 4096
if( 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 Size
mib[] = CTL_HW;
mib[] = HW_MEMSIZE;
long ram;
len = sizeof(ram);
if (sysctl(mib, , &ram, &len, NULL, )) {
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!");
} double vm_total = vm_stats.wire_count + vm_stats.active_count + vm_stats.inactive_count + vm_stats.free_count;
double vm_wire = vm_stats.wire_count;
double vm_active = vm_stats.active_count;
double vm_inactive = vm_stats.inactive_count;
double vm_free = vm_stats.free_count;
double unit = (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、关于Ram大小,用HW_MEMSIZE计算得到1000MB,是准确的

2、关于page size,上面提供了三种方法

其中方法一、二在64位机器上返回了16384,只有第三种方法返回了4096

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

这篇文章提出了此疑问,但是没有特别明确的解释

我认为page size应该是4096,用VM Tracker运行,截图如下:

以第一项_LINKEDIT为例,13692*4096/1024/1024=53.48M,与Vitual Size吻合

3、关于vm_total、vm_wire、vm_active、vm_inactive、vm_free这几个值

其中一组运行结果如下:

Page size is  bytes
Ram size is 1000.000000 MB
-- ::41.191 CompSDKDemo[:] Total Memory: 777.519531
-- ::41.191 CompSDKDemo[:] Wired Memory: 205.484375
-- ::41.192 CompSDKDemo[:] Active Memory: 374.941406
-- ::41.192 CompSDKDemo[:] Inactive Memory: 175.710938
-- ::41.192 CompSDKDemo[:] Free Memory: 21.382812

可以看到,Total Memory不是1000MB,这个如何解释呢?

a. 1000M应该是实际的RAM大小,而Total Memory,应该是Virtual Memory,两者是否一回事,有待商榷?

b. 从APP Store上下了一个System Monitor,如下:

可以看到,Wired、Active、Inactive的值都对得上,唯独Free的值对不上

不负责任的猜测,他的Free是通过1000M减其它三项得到的

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

总结下来,关于内存的有两个问题:

1. active、inactive、wired、free加起来不等于1000M

  这个可以先放一放,我们可以先不用管这部分

2. 当前app消耗的内存,目前的算法与 Debug Gauges的值有偏差,与GT吻合

  不过发现点击页面增长的值和发回释放的值,与Debug Gauges基本一致,因此可以使用

关于CPU,上面算法给出的值符合要求,可以使用;

接下来是:耗电量、网速、帧率

2015.11.23

耗电量,目前没有找到合适的工具

有两种获取电池电量信息的方法

方法一:

这个方法需要导入 IOKit 库,但是不知从什么时候开始,iOS系统不允许用户导入库

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

这篇文章提供了野路子方法,但是实施起来颇为不便,考虑到要做sdk,不适合

CFTypeRef blob = IOPSCopyPowerSourcesInfo();
CFArrayRef sources = IOPSCopyPowerSourcesList(blob);

方法二:

[UIDevice currentDevice].batteryLevel

据说精度达到1%

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

iOS开发之runtime精准获取电池电量

http://www.jianshu.com/p/11c1afdf5415

网络流量

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

2015.11.24

经测试,mach方法获取的内存值与top命令拿到的RSS、VSS是一致的

iOS 获取APP的CPU、内存等信息的更多相关文章

  1. iOS获取app图标和启动图片名字(AppIcon and LaunchImage's name)

    在某种场景下,可能我们需要获取app的图标名称和启动图片的名称.比如说app在前台时,收到了远程通知但是通知栏是不会有通知提醒的,这时我想做个模拟通知提示,需要用到icon名称:再比如在加载某个控制器 ...

  2. iOS获取设备型号、设备类型等信息

    摘自 :http://www.mamicode.com/info-detail-1165460.html 设备标识 关于设备标识,历史上盛行过很多英雄,比如UDID.Mac地址.OpenUDID等,然 ...

  3. 获取APP应用的包名信息

    语言: python 3.7 需求:获取APP的包名和程序入口信息,以便在 Appium 脚本中配置 appPackage 和 appActivity 参数. 场景一 资源:已有APP应用的apk安装 ...

  4. iOS - 获取音视频文件的Metadata信息

    // // MusicInfoArray.h // LocationMusic // // Created by Wengrp on 2017/6/22. // Copyright © 2017年 W ...

  5. ios 获取app版本号

    let infoDictionary = Bundle.main.infoDictionary!let appversion = infoDictionary["CFBundleShortV ...

  6. C#-获取磁盘,cpu,内存信息

    获取磁盘信息 zongdaxiao = GetHardDiskSpace("C") * 1.0 / 1024; user = GetHardDiskFreeSpace(" ...

  7. iOS 获取APP相关信息 私有API

    /* Generated by RuntimeBrowser Image: /System/Library/Frameworks/MobileCoreServices.framework/Mobile ...

  8. iOS 获取 APP 的 Launch Image

    http://www.cocoachina.com/ios/20151027/13780.html 作者:里脊串 授权本站转载. 启动图(LaunchImage)的管理其实在iOS开始中算比较简单的了 ...

  9. iOS 获取app进程被杀死事件

    程序被用户双击上滑杀死后,就对app做一些特殊的处理 下面的方法可以获取到用户双击上滑杀死的事件 - (void)applicationDidEnterBackground:(UIApplicatio ...

随机推荐

  1. VS2008、 VS2010 、 VS2012、 VS2013 都能用的快捷键

    VS2008.  VS2010  . VS2012.  VS2013 都能用的快捷键 Ctrl+E,D             --格式化全部代码 Ctrl+K,F              --格式 ...

  2. 初识Socket通信:基于TCP和UDP协议学习网络编程

    学习笔记: 1.基于TCP协议的Socket网络编程: (1)Socket类构造方法:在客户端和服务器端建立连接 Socket s = new Socket(hostName,port);以主机名和端 ...

  3. 关于Java中用Double型运算时精度丢失的问题

    注:转自 https://blog.csdn.net/bleach_kids/article/details/49129943 在使用Java,double 进行运算时,经常出现精度丢失的问题,总是在 ...

  4. Jms学习篇一:JMS介绍

    1.JMS介绍: JMS即Java消息服务(Java Message Service)应用程序接口,是一个Java平台中关于面向消息中间件(MOM)的API JMS是一种与厂商无关的 API,用来访问 ...

  5. ubuntu GITLAB完全导入SVN(提交历史,用户)项目

    从SVN导入到GITLAB目前没有直接的方案,通常需要通过GIT转换:SVN –>GIT –>GITLAB.通过这种方式,将SVN的提交历史,用户信息一并导入到gitlab 注:本文只适用 ...

  6. TiDB, Distributed Database

    https://www.zhihu.com/topic/20062171/top-answers

  7. ppt写作的注意事项

    PPT推荐字体及大小: 宋体严谨,适合正文,显示最清晰 黑体庄重,适合标题,或者强调区 隶书楷体,艺术性强,不适合投影 如果通过文字排版突出重点:加粗.加大字号.变色 PPT文字太多怎么办? 1.抽象 ...

  8. ListView下拉刷新和PullToRefreshListView实现

    下拉刷新-------    1.addHeaderView必须在setAdapter之前调用    2.将paddingTop设置一个headerView高度的负值去隐藏它        getHe ...

  9. 怎样在vs2013和vs2015中实现自动编译sass

    Visual Studio不论是2013版本还是2015版本要自动编译都需要添加扩展. 添加扩展的方法,路径“工具”->“扩展和更新”,在打开的窗口“搜索”你需要的扩展根据提示“下载”和“安装” ...

  10. MSSQL的SQL语句独立执行消耗与线上执行消耗差异

    环境: SQL Server 2012 疑问:同样的一条语句,使用Profile跟踪出来的消耗与单独拿出来执行的消耗存在非常大的差距 语句如下: declare @str nvarchar(max) ...