2023年11月30日发(作者:)

iOSInstruments使⽤

⼀、Instruments介绍

Instruments ⼀个很灵活的、强⼤的⼯具,是性能分析、动态跟踪 和分析OS X以及iOS代码的测试⼯具,⽤它可以极为⽅便收集关于⼀个

或多个系统进程的性能和⾏为的数据,并能及时随着时间跟踪⽽产⽣的数据,并检查所收集的数据,还可以⼴泛收集不同类型的数据.也可以

追踪程序运⾏的过程,这样instrument就可以帮助我们了解⽤户的应⽤程序和操作系统的⾏为。

总结⼀下instrument能做的事情:

1. Instruments是⽤于动态调追踪和分析OS XiOS的代码的性能分析和测试⼯具;

ments⽀持多线程的调试;

3.可以⽤Instruments去录制和回放,图形⽤户界⾯的操作过程

4.可将录制的图形界⾯操作和Instruments保存为模板,供以后访问使⽤。

instrument还可以:

1.追踪代码中的(甚⾄是那些难以复制的)问题;

2.分析程序的性能;

3.实现程序的⾃动化测试;

4.部分实现程序的压⼒测试;

5.执⾏系统级别的通⽤问题追踪调试;

6.使你对程序的内部运⾏过程更加了解。

打开⽅式:

Xcode -> Open Developer Tool -> Instruments

其中⽐较常⽤的有四种:

Allocations:⽤来检查内存分配,跟踪过程的匿名虚拟内存和堆的对象提供类名和可选保留/释放历史

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

Automation:⽤JavaScript语⾔编写,主要⽤于分析应⽤的性能和⽤户⾏为,模仿/击发被请求的事件,利⽤它可以完成对被测应⽤

的简单的UI测试及相关功能测试

Cocoa Layout:观察约束变化,找出布局代码的问题所在。

Core Animation:⽤来检测Core Animation性能的,给我们提供了周期性的FPS,并且考虑到了发⽣在程序之外的动画,界⾯滑动

FPS可以进⾏测试

Core Data:监测读取、缓存未命中、保存等操作,能直观显⽰是否保存次数远超实际需要

Energy Diagnostic :⽤于Xcode下的Instruments来分析⼿机电量消耗的。(必须是真机才有电量)

GPU Driver :可以测量GPU的利⽤率,同样也是⼀个很好的来判断和GPU相关动画性能的指⽰器。它同样也提供了类似Core

Animtaion那样显⽰FPS的⼯具。

Network:分析应⽤程序如何使⽤TCP / IP和UDP / IP连接使⽤连接仪器。就是检查⼿机⽹速的。(这个最好是真机)

⼆、Allocations(分配)

1.内存分类:

Leaked memory:泄漏的内存,如为对象A申请了内存空间,之后再也没⽤到A,也没有释放A导致内存泄漏(野指针。。。)

Abandoned memory:被遗弃的内存,如循环引⽤,递归不断申请内存⽽导致的内存泄漏

我们可以在程序运⾏时,在进⼊某个模块前标记⼀个Generation,这样会⽣成⼀个快照。然后进⼊、退出,再标记⼀个Generation,如下

其中growth就是我们增长的内存,GenerationA是程序启动到进⼊该场景增长的内存,GenerationB就是第⼆次进⼊该场景所增长的内

存,查看⼦类可以发现有两个管理类造成了Abandoned memory

3.设置Generations

使⽤instrument测试内存泄露 ⼯具 Allocations 测试是否内存泄露 使⽤标记,可以更省事省⼒的测试页⾯是否有内存泄露

1)设置Generations

3)使⽤⽅法 在进⼊测试页⾯之前,mark⼀下----->进⼊页⾯----->退出----->mark------>进⼊------->退出------->mark------>进⼊如此往复

5、6次,就可以看到如下结果

这种情况下是内存有泄露,看到每次的增量都是好⼏百K或者上M的,都是属于内存有泄露的,这时候就需要检测下代码⼀般情况下,100K

以下都属于正常范围,growth表⽰距离你上次mark的增量

三、Leaks(泄漏)

1.内存溢出和内存泄漏的区别

内存溢出 out of memory,是指程序在申请内存时,没有⾜够的内存空间供其使⽤,出现out of memory;⽐如申请了⼀个integer,但给

它存了long才能存下的数,那就是内存溢出。

内存泄露 memory leak,是指程序在申请内存后,⽆法释放已申请的内存空间,⼀次内存泄露危害可以忽略,但内存泄露堆积后果很严

重,⽆论多少内存,迟早会被占光。

常发性内存泄漏。发⽣内存泄漏的代码会被多次执⾏到,每次被执⾏的时候都会导致⼀块内存泄漏。

偶发性内存泄漏。发⽣内存泄漏的代码只有在某些特定环境或操作过程下才会发⽣。常发性和偶发性是相对的。对于特定的环境,偶

在详情⾯板选中显⽰的若⼲条中的⼀条,双击,会⾃动跳到内存泄露代码处,然后点击右上⾓ Xcode 图标进⾏修改。

1. 在 Display Settings 界⾯建议把 Snapshot Interval (snapʃɒt, 数据快照)间隔时间设置为10秒,勾选Automatic

Snapshotting,Leaks 会⾃动进⾏内存捕捉分析。(新版本直接在底部修改)

2. 熟练使⽤ Leaks 后会对内存泄漏判断更准确,在可能导致泄漏的操作⾥,在你怀疑有内存泄漏的操作前和操作后,可以点击

Snapshot Now 进⾏⼿动捕捉。

3. 开始时如果设备性能较好,可以把⾃动捕捉间隔设置为 5 秒钟。

4. 使⽤ARC的项⽬,⼀般内存泄漏都是 malloc、⾃定义结构、资源引起的,多注意这些地⽅进⾏分析。

5. 开启ARC后,内存泄漏的原因

开启了ARC并不是就不会存在内存问题,苹果有句名⾔:ARC is only for NSObject。

注:如果你的项⽬使⽤了ARC,随着你的操作,不断开启或关闭视图,内存可能持续上升,但这不⼀定表⽰存在内存泄漏,ARC释放的时

机是不固定的。

这⾥对 Display Settings中 的 Call tree 选项做⼀下说明 [官⽅user guide翻译]:

Separate By Thread:线程分离,只有这样才能在调⽤路径中能够清晰看到占⽤CPU最⼤的线程.每个线程应该分开考虑。只有这样你

1)界⾯详情:

5)样本列表

五、Zombies(僵⼫)

1.概念

翻译英⽂:专注于检测过度释放的“僵⼫”对象。还提供了数据对象分配的类以及所有活动分配内存地址的历史。

这⾥我们可以看到⼀个词语叫“over-release”,过度释放。我们在项⽬中见到最多的就是“EXC_BAD_ACCESS”或者是这样的:

Thread 1: Program received signal:"EXC_BAD_ACCESS",这就是访问了被释放的内存地址造成的。

我们将僵⼫对象“复活”的⽬的:僵⼫对象就是让已经释放了的对象重新复活,便于调试;是为了让已经释放了的对象在被再次访问时能够

输出⼀些错误信息。其实这⾥的“复活”并不是真的复活,⽽是强⾏不死:这么说吧 相当于 他的RC=0的时候 系统再强⾏让他RC=1,顺

注意:Zombies模版在使⽤的时候会导致内存的飙升,这是因为所有被释放的对象被僵⼫对象取代,并未真的释放掉,在结束Zombies时

最后提醒的是NSZombieEnabled只能在调试的时候使⽤,千万不要忘记在产品发布的时候去掉,因为NSZombieEnabled不会真正去释放

dealloc对象的内存,⼀直开启的话,该死去的对象会⼀直存在,后果可想⽽知,⾃重!

六、扩展

野指针

C语⾔: 当我们声明1个指针变量,没有为这个指针变量赋初始值.这个指针变量的值是1个垃圾指 指向1块随机的内存空间。

OC语⾔: 指针指向的对象已经被回收掉了.这个指针就叫做野指针.

默认情况下. Xcode不会去检测指针指向的对象是否为1个僵⼫对象. 能访问就访问 不能访问就报错.

可以开启Xcode的僵⼫对象检测.

那么就会在通过指针访问对象的时候,检测这个对象是否为1个僵⼫对象 如果是僵⼫对象 就会报错.

为什么不默认开启僵⼫对象检测呢?

因为⼀旦开启,每次通过指针访问对象的时候.都会去检查指针指向的对象是否为僵⼫对象.