Instruments

Instruments 是一个很灵活的、强大的工具;是性能分析、动态跟踪 和分析 OS X 以及 iOS 代码的测试工具;用它可以极为方便收集关于一个或多个系统进程的性能和行为的数据,并能及时随着时间跟踪而产生的数据,并检查所收集的数据,还可以广泛收集不同类型的数据;也可以追踪程序运行的过程,这样 instrument 就可以帮助我们了解用户的应用程序和操作系统的行为。

由于Instruments是对app性能的检测, 所以强烈建议在真机上调试, 结果更加精准.

instrument 基本工具如下(未列举详尽):

  • Leaks(泄漏):一般的查看内存使用情况,检查泄漏的内存,并提供了所有活动的分配和泄漏模块的类对象分配统计信息以及内存地址历史记录;

  • Time Profiler(时间探查):执行对系统的 CPU上运行的进程低负载时间为基础采样。
  • Core Animation: 检测几面流畅度(帧率检测, 一般低于30fps就会卡顿)

  • Allocations(内存分配):跟踪过程的匿名虚拟内存和堆的对象提供类名和可选保留/释放历史;

  • Activity Monitor(活动监视器):显示器处理的 CPU、内存和网络使用情况统计;
  • Blank(空模板):创建一个空的模板,可以从 Library 库中添加其他模板;

  • Automation(自动化):这个模板执行它模拟用户界面交互为 iOS 手机应用从 instrument 启动的脚本;
  • Core Data:监测读取、缓存未命中、保存等操作,能直观显示是否保存次数远超实际需要。
  • Cocoa Layout:观察约束变化,找出布局代码的问题所在。
  • Network:跟踪 TCP/IP 和 UDP/IP 连接。
  • Automations:创建和编辑测试脚本来自动化 iOS 应用的用户界面测试。
  • Energy Log: 检测应用在不同时刻,不同状态的耗电量.(例如,开启gps, wifi, bluetooth等)

Instruments 最常用的四大类:

  • Leaks:找到引发内存泄漏的起点

  • Time Profiler:分析代码的执行时间,找出导致程序变慢的原因

  • Core Animation: 检测几面流畅度(帧率检测, 一般低于30fps就会卡顿)

  • Allocations:监测内存使用/分配情况

快速开启Instruments的快捷键:

ctrl + cmd + i

内存泄露检测(Leaks)

打开Intruments, 选择Leaks, 就会打开Leaks的调试面板. 点击调试面板左上角红色的开始录制按钮, 那么就开始了内存泄露的检测. 你只需在手机上正常使用app, 或者直接跳转到你觉得有内存泄露的功能模块进行测试.如下图所示:

首先我们将面板分成上下两个区域, 上面是状态, 根据测试时间像磁带一样不停运动,并记录存在内存泄露的地方,用红色的叉叉(箭头1)标示出来,没有泄露的地方用灰色的减号标示. 下面是详情区域, 当点击上面出现内存泄露的红色标记时, 就会在下面显示泄露的详情, 双击详情区左边列表(箭头2), 会在详情区右边(箭头3)列出具体出现泄露的类名等信息, 双击就能在代码中显示.

一般来说,在创建工程的时候,我都会在Build Settings启用Analyze During ‘Build’,每次编译时都会自动静态分析。这样的话,写完一小段代码之后,就马上知道是否存在内存泄露或其他bug问题,并且可以修bugs。而在运行过程中,如果出现EXC_BAD_ACCESS,启用NSZombieEnabled,看出现异常后,控制台能否打印出更多的提示信息。如果想在运行时查看是否存在内存泄露,使用Instrument Leak工具。但是有些内存泄露是很难检查出来,有时只有通过手动覆盖dealloc方法,看它最终有没有调用。

Time Profiler

点击Time Profiler应用程序开始运行后.就能获取到整个应用程序运行消耗时间分布和百分比.为了保证数据分析在统一使用场景真实行有如下点需要注意:

在开始进行应用程序性能分析的时候,一定要使用真机,模拟器运行在Mac上,然而Mac上的CPU往往比iOS设备要快。相反,Mac上的GPU和iOS设备的完全不一样,模拟器不得已要在软件层面(CPU)模拟设备的GPU,这意味着GPU相关的操作在模拟器上运行的更慢,尤其是使用CAEAGLLayer来写一些OpenGL的代码时候. 这就导致模拟器性能数据和用户真机使用性能数据相去甚运.

另外在开始性能分析前另外一件重要的事情是,应用程序运行一定要发布配置 而不是调试配置.

在发布环境打包的时候,编译器会引入一系列提高性能的优化,例如去掉调试符号或者移除并重新组织代码.另iOS引入一种”Watch Dog”[看门狗]机制.不同的场景下,“看门狗”会监测应用的性能。如果超出了该场景所规定的运行时间,“看门狗”就会强制终结这个应用的进程.开发者可以crashlog看到对应的日志.但Xcode在调试配置下会禁用”Watch Dog”.

当日志太多可以设置过滤

Separate By Thread:线程分离,只有这样才能在调用路径中能够清晰看到占用CPU最大的线程.

Invert Call Tree:从上到下跟踪堆栈信息.这个选项可以快捷的看到方法调用路径最深方法占用CPU耗时,比如FuncA{FunB{FunC}},勾选后堆栈以C->B->A把调用层级最深的C显示最外面.

Hide Missing Symbols:如果dSYM无法找到你的APP或者调用系统框架的话,那么表中将看到调用方法名只能看到16进制的数值,勾选这个选项则可以隐藏这些符号,便于简化分析数据.

Hide System Libraries:这个就更有用了,勾选后耗时调用路径只会显示app耗时的代码,性能分析普遍我们都比较关系自己代码的耗时而不是系统的.基本是必选项.注意有些代码耗时也会纳入系统层级,可以进行勾选前后前后对执行路径进行比对会非常有用.

Core Animation

参考如下文章

Allocations

参考如下文章

Energy Logs

参考如下文章