一、介绍说明
Instrument是
性能分析、动态跟踪
和分析OS X和iOS代码的测试工具。常见有CPU性能测试
、图形性能测试
、内存性能测试
等,可以让您追踪程序运行的过程,收集数据,并检查所收集的数据。1、通过Xcode工具栏中Product->Profile(command+i)启动界面
2、建议使用真机测试,数据会更可靠。模拟器运行和真机运行的CPU有差别。
3、应用程序运行一定要发布配置 而不是调试配置。
1、界面如下:
2、功能说明:
1.追踪代码中的(甚至是那些难以复现
的)问题;\
2.分析程序的性能(CPU、内存性能等
);
3.实现程序的自动化测试
;
4.部分实现程序的压力测试
;
5.执行系统级别的通用问题追踪调试;
6.了解程序的内部运行
过程。
3、常用模板:
Leaks(泄漏)
:一般的查看内存使用情况
,检查泄漏
的内存,并提供了所有活动的分配和泄漏模块的类对象分配统计信息以及内存地址历史记录;
Time Profiler(时间探查)
:执行对系统的 CPU上运行的进程低负载时间
为基础采样。
Allocations(内存分配)
:跟踪过程的匿名虚拟内存和堆的对象提供类名和可选保留/释放历史;
Activity Monitor(活动监视器)
:显示器处理的 CPU、内存和网络使用情况统计;
Blank(空模板)
:创建一个空的模板,可以从Library 库
中添加其他模板;
Automation(自动化)
:这个模板执行它模拟用户界面交互
为 iOS 手机应用从 instrument 启动的脚本;
Core Data:监测读取、缓存未命中、保存等操作,能直观显示是否保存次数远超实际需要。
Cocoa Layout
:观察约束
变化,找出布局代码
的问题所在。
Network
:跟踪 TCP/IP
和 UDP/IP
连接。
Automations
:创建和编辑测试脚本
来自动化
iOS 应用的用户界面测试
。
4、工具界面:
1、控制记录过程,点击红色的"记录"按钮可以停止或开始
当前正在分析的app(在记录和停止按钮之间切换),暂停键,暂停当前正在运行的app。
2、执行计时器(run timer),计时器记录着正在分析的app执行了多长时间
、执行了多少次
。如果你使用记录控制按钮来停止你的app,然后重启,这将创建一个新的运行记录,同时会显示"Run 2 of 2"。
3、被称作路径(track),如你选择的Time Profiler工具而言,因为只有一个工具
,所以这里只有一条路径
。
4、详情面板,展示你正在使用的工具的主要信息。如图展示的是最"笨重(hottest)"的方法—即占用CPU时间最长
的方法。点击上方的bar会看到Call Tree(左手边的那个)并选中Sample List,会看到数据的不同视图,视图展示了每一个示例。点击其中几个,会在Extended Detail inspector中看到被捕获的堆栈跟踪
。
5、检查器(inspector)面板,一共有三个检查器:record setting(记录设置)
,display setting(展示设置)
,和extends detail(扩展详情)
。
5、Call Tree各个选项和功能:
Separate by Thread: 每个线程应该分开考虑
。只有这样你才能揪出那些大量占用CPU的"重"线程
Invert Call Tree: 从上到下
跟踪堆栈,表中的方法将从第0帧开始取样,也就是说FuncA{FunB{FunC}} 勾选此项后堆栈以C->B-A 把调用层级最深
的C显示在最外面
Hide Missing Symbols: 如果dSYM
无法找到你的app或者系统框架的话,那么表中看不到方法名
只能看到十六进制
的数,如果勾线
此项可以隐藏
这些符号,便于简化数据
Hide System Libraries: 勾选此项会显示app的代码
,这是非常有用的,因为通常你只关心cpu花在自己代码上的时间
不是系统上的时间
Show Obj-C Only: 只显示oc代码
,如果你的程序是像OpenGl这样的程序,则不要勾选,因为他有可能是C++
的
Flatten Recursion: 递归函数
, 每个堆栈跟踪一个条目
Top Functions: 这个选项让 Instruments 将一个函数的整个CPU 时间
看成是在该函数
中用去的 CPU 时间的总合
,也就是该函数调用
了的所有函数
所花去的时间。比如函数 A 调用了函数 B,则 A 的时间就是 A 花去的时间加上 B 花去的时间。它允许你在追溯调用栈时获得最大
的时间数,在你最耗时
的方法上归零
。
二、工具使用
1、Time Profiler
时间分析工具:
用来检测
CPU
性能、各个方法
执行的时间
1.选择 Time Profiler
,并点击Choose
按钮。
2.选择正确的设备和应用程序
3.点击红色按钮
运行后,就能得到 CPU 性能的结果
4.勾选右边Call Tree
中Separate by Thread
、Invert Call Tree
和 Hide System Libraries
选项后,可以看到对应的代码
执行耗时
例如下面的结果,找出哪一行的 Weight 列上有最大
的百分比。注意 Main Thread 一行使用了一个很大
的 CPU 百分比。点击左边的小箭头
,展开这行,不停向下展开直到看到你自己的方法
(有一个人像图标
标出的方法)。可能某些数字略有不同,但各行数据的顺序应当类似如下所示:
可以看到大量的时间被花在了使用“tonal”滤镜
的方法上。接下来找出这个方法中到底做了些什么。
5.双击该方法
,可以看到代码详情
。打开如下这个界面:
发现不太好提升性能:创建 CGImage 方法本身花费的时间就是需要这么长,那么可以看看 applyTonalFilter()方法
是如何调用的。在代码视图的顶部,点击面包屑导航尾部的 Root,回到之前的界面:
现在点击顶部applyTonalFilter
左边的小箭头。这会显示出 applyTonalFilter 的调用者
。你还需要展开下一行,在 Profile Swift 时,有时候会在调用树中存在一些相同的行,前缀中包含 @objc。你感兴趣的是第一行,它以一个人像图标作为前缀,这表明它属于你 app 的 target:
可以看到调用者是 collection view 的(_:cellForItemAt:)方法
。双击
这行可以查看相关源代码如下图:
不难看出第 75 行,这个方法使用了耗时
的 tonal 滤镜,而且它是直接在 collectionView(_:cellForItemAt:) 方法中调用的,这样每当获取一张滤镜图片的时候就会对主线程(以及整个 UI)造成阻塞
。
要解决这个问题,需要采取两个措施:首先,使用 DispatchQueue.global().async 方法
将图像滤镜的生成拆解到后台线程
中进行;然后在图像生成后对图像进行缓存
。判断如果有缓存则直接用缓存。
现在需要回到 Xcode进行代码操作:
1、可以手动
找出你在 Instruments 中看到的源代码
2、更简单的方法,面板的代码上面有个 Open in Xcode
按钮,点击它Xcode 会自动打开
并定位
到正确的地方:
2、Core Animation
评估图形性能
用于调试
离屏渲染
,绘图
,动画
,图层混合
等GPU耗时
操作
1.选择 Core Animation,并点击 Choose按钮。
2.选择正确的设备和应用程序
3.点击红色按钮运行后,随着我们操作 App,就能得到数据
在右边面板的 Settings 区域,我们可以看到多个 Debug Options:
Color Blended Layers
这个选项基于渲染程度对屏幕中的混合区域进行绿到红
的高亮显示,越红
表示性能越差
,会对帧率等指标造成较大的影响。红色通常是由于多个半透明图层叠加引起。
Color Hits Green and Misses Red
当 UIView.layer.shouldRasterize = YES
时,耗时的图片绘制会被缓存
,并当做一个简单的扁平图片来呈现。这时候,如果页面的其他区块(比如 UITableViewCell 的复用)使用缓存直接命中,就显示绿色
,反之不命中,就显示红色
。红色越多,性能越差
。因为栅格化
生成缓存的过程是有开销
的,如果缓存能被大量命中和有效使用,则总体上会降低开销,反之则意味着要频繁生成新的缓存,这会让性能问题雪上加霜。
Color Copied Images
对于GPU 不支持
的色彩格式的图片只能由 CPU
来处理,把这样的图片标为蓝色
。蓝色越多,性能越差
。因为,我们不希望在滚动视图
的时候,由 CPU
来处理图片,这样可能会对主线程
造成阻塞
。
Color Immediately
通常 Core Animation Instruments 以每毫秒 10 次
的频率更新图层调试颜色。对某些效果来说,这显然太慢了。这个选项就可以用来设置每帧都更新(可能会影响到渲染性能
,而且会导致帧率测量不准,所以不要一直都设置它)。
Color Misaligned Images
这个选项检查了图片是否被缩放
,以及像素
是否对齐
。图片被放缩
的会被标记为黄色
,像素不对齐
则会标注为紫色
。黄色、紫色越多,性能越差
。
Color Offscreen-Rendered Yellow
这个选项会把那些离屏渲染
的图层显示为黄色
。黄色越多,性能越差
。这些显示为黄色的图层很可能需要用 shadowPath
或者 shouldRasterize
来优化
。
Color OpenGL Fast Path Blue
这个选项会把任何直接
使用 OpenGL 绘制
的图层显示为蓝色
。蓝色越多,性能越好
。如果仅仅使用UIKit
或者 Core Animation
的 API,那么不会有任何效果。如果使用 GLKView
或者CAEAGLLayer
,那如果不显示蓝色块的话就意味着你正在强制 CPU 渲染
额外的纹理,而不是绘制到屏幕。
Flash Updated Regions
这个选项会把重绘
的内容显示为黄色
。不该
出现的黄色越多,性能越差
。通常我们希望只是更新
的部分被标记为黄色
。
3、Leaks
用来检测内存泄露
1.选择 Leaks,并点击 Choose按钮。
2.选择正确的设备和应用程序
3.点击红色按钮运行后,随着我们操作 App,就能得到数据
4.可在下图这个位置选择,展示的不同模式
5.在Call Trees模式下,在Settings 中勾选 Invert Call Tree 或 Hide System Libraries,或其他选项可以过滤显示的数据。
6.出现内存泄露的情况
7.选中上图的Leak Checks 一栏
8.然后点击导航栏切换到“Call Tree”模式
9.勾选右边的详细窗口 Display Settings中的 Call Tree中 Separate by Thread和 Hide System Libraries两个选项,Hide System Libraries作用是隐藏系统函数。能方便的看到程序中代码所在的位置。
10.勾选之后,双击一下就会来到内存泄漏的地方
参考资料:
https://www.jianshu.com/p/e6b4726b4439
https://www.jianshu.com/p/660c4601cfc8