Instruments 使用教程

Instruments 使用教程


Instruments有很多强大的功能,它原生支持很多Instruments工具,帮我们分析代码,包括内存检测、自动化检测、监测文件读写操作等等。掌握Instruments常用的基本功能,能让我们的编程得心应手。


下面的例子是在没有ARC的情况下,如何使用Instruments来查找程序中的内存泄露,以及NSZombieEnabled设置的使用。

本文假设你已经比较熟悉Obj-C的内存管理机制。

实验的开发环境:XCode 4.5.2

1、运行demo

先下载一个实现准备好的内存泄露的Demo吧:leak app

下载下来,打开运行,程序是一个寿司的列表,列出各种寿司卷。试着选择里面的几行,应该是选第二行的时候就崩溃了。崩溃截图:


Instruments 使用教程_第1张图片

在崩溃的地方断住了,知道crash的地方了,但是不知道具体crash的原因。

2、设置NSZombieEnabled

这是一个 “EXC_BAD_ACCESS”错误。我们打开XCode的选项:“NSZombieEnabled” 。在crash时可能会给你更多的一些提示信息。

设置步骤:1

Instruments 使用教程_第2张图片

2:勾上红色框里的

Instruments 使用教程_第3张图片

运行,按刚才的操作选中其中的cell。再次crash,这次在output窗口会看到多了一项错误信息:

2012-11-28 13:22:08.911 PropMemFun[2132:11303] *** -[CFString respondsToSelector:]: message sent to deallocated instance 0x713ebc0

大概意思是:向已释放的内存发送消息。也就是说使用了已释放的内存,在C语言相当于使用了“野指针”

Instruments 使用教程_第4张图片

看了下crash的这个语句,sushiString应该是没问题的,它是从stringWithFormat初始化出来的。那就是_lastSushiSelected的问题。

_lastSushiSelected指向了sushiString,sushiString是一个autorelease变量。 在第二次点击时,使用的是sushiString已经被释放,所以crash了。那为_lastSushiSelected保留一下,就可以用了。代码修改如下:

[cpp]  view plain  copy
  1. <span style="font-size:14px;">    _lastSushiSelected = [sushiString retain];  
  2. </span>  

运行,这时候不崩溃。

3、分析内存泄露(shift+command+b)

app不crash了,那看看有没有内存泄露。用XCode的Analyze就能分析到哪里有内存泄露

Instruments 使用教程_第5张图片

分析之后可以看到:

Instruments 使用教程_第6张图片

这里提示alertView没被释放,有内存泄露,那我们释放

    [alertView release];

再分析,这个问题解决了。

4、使用Instruments的leaks工具

分析内存泄露不能把所有的内存泄露查出来,有的内存泄露是在运行时,用户操作时才产生的。那就需要用到Instruments了。
Instruments 使用教程_第7张图片 
按上面操作,build成功后跳出 Instruments工具,选择Leaks选项,这时候寿司程序也运行起来了,选中list中的项,拖动等操作后,工具显示效果如下:
Instruments 使用教程_第8张图片

大家可能都能猜到,红色的柱子表示内存泄露了。怎么通过这个工具看到在哪泄露了呢?
先在工具栏按下红色的圆形按钮,把工具监视内存的活动停下来。选择Leak,然后点中间十字交叉那,选择Call Tree. Instruments 使用教程_第9张图片


这时候左下角的Call Tree的可选项可以选了。选中Invert Call Tree 和Hide System Libraries,显示如下:
Instruments 使用教程_第10张图片

这时候内存泄露的具体代码找到了,在右边的红色框框里指定了哪个方法出现了内存泄露。
你只要在这些方法上双击,就会跳转到具体的代码,哈哈,是不是很方便。
Instruments 使用教程_第11张图片
这里应该是提示100%内存会泄露。
5、解决内存泄露问题

关于tableView:didSelectRowAtIndexPath ,分析下它的内存过程:

  1. sushiString变量通过autorelease创建,它的引用计数是1.   
  2. 这行代码使得引用计数增加到2, _lastSushiSelected = [sushiString retain];
  3. 这个方法结束时,sushiString的autorelease生效了,这个变量的引用计数减少为1
  4. 当再次执行tableView:didSelectRowAtIndexPath这个方法时,_lastSushiSelected被赋值了新指针,老的_lastSushiSelected的引用计数还是1,没有被释放,产生了内存泄露。

怎么解决呢?

_lastSushiSelected = [sushiString retain];之前把原来的release就ok了:

[cpp]  view plain  copy
  1. [_lastSushiSelected release];  
  2.     _lastSushiSelected = [sushiString retain];  

关于tableView:cellForRowAtIndexPath

这个比较明显, sushiString被alloc和init之后就没有释放,可以用stringWithFormat来调用autorelease,代码如下:

[cpp]  view plain  copy
  1. NSString *sushiString = [NSString stringWithFormat:@"%d: %@", indexPath.row, sushiName];  

好了,泄露都fix了,再用工具分析看看,这时候你再点,再拖,再怎么操作,都没有内存泄露了。表明内存泄露被堵住了。


推荐一篇翻译过得英文原文档,希望对你有用。

以下提供目录预览:


目录

INSTRUMENTS用户指南介绍    
本文档组织结构    
第一章    INSTRUMENTS快速入门    
    1.1    启动INSTRUMENTS    
    1.2    创建一个跟踪文档    
    1.3    浏览跟踪文档窗口    
   1.4    示例:快速使用一个跟踪    
   1.5    下一步是什么?    
第二章    添加和配置INSTRUMENTS工具    
    2.1    使用INSTRUMENT库    
        2.1.1    修改库试图模式    
        2.1.2    查找库里面的某个instrument工具    
        2.1.3    新建一个自定义的instrument分组    
    2.2    添加和删除INSTRUMENTS工具    
    2.3    配置一个INSTRUMENT工具    
第三章    记录跟踪数据    
    3.1    选择需要跟踪的进程    
        3.1.1    跟踪所有进程    
        3.1.2    跟踪一个已有的进程    
        3.1.3    跟踪一个新的进程    
        3.1.4    给每个Instrument工具指定不同的目标    
    3.2    收集数据    
    3.3    使用快速启动键启动INSTRUMENTS    
    3.4    以最小模式运行    
    3.5    从XCODE运行INSTRUMENTS应用    
    3.6    无线连接IOS设备    
第四章    记录用户界面轨迹    
    4.1    记录用户界面轨迹    
    4.2    重复记录用户界面轨迹    
    4.3    回放用户界面轨迹    
第五章    查看和分析跟踪数据    
    5.1    查看数据的工具    
        5.1.1    跟踪面板    
        5.1.2    详细面板    
        5.1.3    扩展详细面板    
        5.1.4    运行浏览器    
    5.2    分析技术    
        5.2.1    使用Sampler Instrument分析数据    
        5.2.2    使用Allocati***** Instrument工具分析数据    
        5.2.3    查找内存泄露    
        5.2.4    分析Core Data应用程序    
第六章    保存和导入跟踪数据    
    6.1    保存跟踪文档    
    6.2    导出跟踪数据    
    6.3    从SAMPLE工具中导入数据    
    6.4    使用DTRACE数据    
第七章    使用DTRACE创建自定义INSTRUMENTS工具    
    7.1    关于自定义INSTRUMENTS工具    
    7.2    创建自定义的INSTRUMENT工具    
        7.2.1    添加和删除探针    
        7.2.2    指定探针的提供者    
        7.2.3    给探针添加断言
        7.2.4    给探针添加动作    
       7.2.5    编写自定义脚本的提示    
       7.2.6    编写BEGIN和END脚本    
       7.2.7    从自定义脚本里面访问内核数据    
       7.2.8    变量作用域    
       7.2.9    查找脚本错误    
    7.3    导出DTRACE脚本    
第八章    内置INSTRUMENTS工具    
    8.1    CORE DATA INSTRUMENTS[CORE DATA相关]    
        8.1.1    Core Data Saves    
        8.1.2    Core Data Fetches    
        8.1.3    Core Data Faults    
        8.1.4    Core Data Cache Misses    
    8.2    DISPATCH INSTRUMENTS[并发相关]    
        8.2.1    Dispatch    
    8.3    ENERGY DIAGNOSITICS INSTRUMENTS[电池诊断相关]    
        8.3.1    电量使用(Energy Usage)    
        8.3.2    CPU 活动(CPU Acitivity)    
        8.3.3    显示亮度(Display Brightness)    
        8.3.4    休眠/唤醒(Sleep/Wake)    
        8.3.5    蓝牙(Bluetooth)
        8.3.6    无线(WiFi)
        8.3.7    定位(GPS)
    8.4    FILE SYSTEM INSTRUMENTS[文件系统相关]    
        8.4.1    I/O 活动(I/O Activity)    
        8.4.2    文件锁(File Locks)    
        8.4.3    文件属性(File Attributes)    
        8.4.4    文件活动(File Activity)    
        8.4.5    目录I/O(Directory I/O)    
    8.5    GARBAGE COLLECTION INSTRUMENTS[垃圾回收相关]    
        8.5.1    GC Total
        8.5.2    垃圾回收(Garbage Collection)
    8.6    GRAPHICS INSTRUMENTS[绘图相关]
        8.6.1    核心动画(Core Animation)
        8.6.2    OpenGL驱动器(OpenGL Driver)
        8.6.3    OpenGL ES驱动器(OpenGL ES Driver)
       8.6.4    OpenGL ES分析器(OpenGL ES Analyzer)
    8.7    INPUT/OUTPUT INSTRUMENTS[输入输出相关]
        8.7.1    读/写(Reads/Wirtes)
    8.8    MASTER TRACKS INSTRUMENTS[界面操作跟踪相关]
        8.8.1    用户界面(User Interface)
    8.9    MEMORY INSTRUMENTS[内存相关]
        8.9.1    共享内存(Shared Memory)
        8.9.2    分配内存(Allocati*****)
        8.9.3    内存泄露(Leaks)
    8.10    SYSTEM INSTRUMENTS[系统相关]    
        8.10.1    时间分析器(Time Profiler)
        8.10.2    旋转监控器(Spin Monitor)
        8.10.3    取样(Sampler)    
        8.10.4    进程(Process)    
        8.10.5    网络活动监控器(Network Activity Monitor)
        8.10.6    内存监控器(Memory Monitor)
        8.10.7    硬盘监控器(Disk Monitor)
        8.10.8    CPU监控器(CPU Monitor)
        8.10.9    活动监控器(Activity Monitor)
    8.11    THREADS/LOCKS INSTRUMENTS[线程相关]
        8.11.1    Java线程(Java Thread)
    8.12    UI AUTOMATION[界面自动化相关]
        8.12.1    使用Automation Instrument工具
        8.12.2    访问和操作用户界面元素
        8.12.3    添加灵活的超时间
        8.12.4    验证测试结果
        8.12.5    输出测试结果和数据的日子
        8.12.6    处理警告
        8.12.7    检测和指定设备的方向
        8.12.8    测试多任务
    8.13    USER INTERFACE INSTRUMENTS[用户界面相关]
        8.13.1    Cocoa事件(Cocoa Events)
        8.13.2    Carbon事件(Carbon Events)
结束语
推荐资源


本文参考:

来源:Instruments User Guide

博客:http://blog.csdn.net/toss156/article/details/7579294

           http://blog.csdn.net/totogo2010/article/details/8233565

网址:https://developer.apple.com/library/ios/documentation/DeveloperTools/Conceptual/InstrumentsUserGuide/index.html

           https://www.raywenderlich.com/




你可能感兴趣的:(ios,编程,内存管理,内存泄露,instruments)