使用Xcode Instruments 定位iOS应用的Memory Leaks

了解:在苹果没有出ARC(自动内存管理机制)时,iOS开发攻城狮几乎有一半的开发时间都消耗在怎么管理内存上后来苹果人性化推出了ARC,虽然在很大程度上帮助我们开发者节省了精力和时间。但是我们在开发过程中,由于种种原因,还是会出现内存泄漏的问题。
内存泄漏是一个很严重的问题,我们先了解一下xcode7自带的Instruments中的Leaks如何检测我们的程序中内存泄漏以及定位内存泄漏代码(Leaks分析内存泄漏并不能把所有的内存泄漏问题查出来,有的内存泄漏时在运行时,用户操作时才会产生的)


简介内存管理:

  • Object-C有3种内存管理方式,他们分别是
    • MRR (Manual Retain Release, 手动保持释放)
    • ARC (Automatic Reference Counting,自动引用计数)
    • GC (Garbage Collection,垃圾收集)
  • 1> MRR
    • ① 也称为 MRC (Manual Reference Counting,手动引用计数)
    • ② 由程序员自己负责管理对象生命周期,负责对象的创建和销毁
  • 2> ARC
    • ① 采用和MRR一样的内存引用计数管理方式
    • ② 在编译时会在适合的位置插入对象内存释放,(如 release, autorelease, 和 retain 等)
    • ③ 程序员不需要关心对象释放的问题,苹果推荐在新项目中使用ARC,但在iOS5之前的项目中不能采用ARC
  • 3> GC
    • ① 在Objective_C2.0之后,内存管理出现了类似于Java和C#的内存垃圾收集技术,但是垃圾收集与ARC一直运行,垃圾收集时后台有一个线程负责检查已经不在使用的对象,然后释放,
    • ② 由于后台有一个线程一直运行,会严重影响性能,这也是java和C#程序的运行速度无法超越C++的主要原因
    • ③ GC技术不能应用于iOS开发,只能使用与Mac OS X开发

内存泄漏

  • 内存泄漏指当一个对象或变量在使用完成后没有释放掉,这个对象一直占用这部分的内存,直到应用停止
  • 这种没有释放掉的对象多了内存就会耗尽,其他应用就无法运行
  • 内存泄漏在C++,C和Objective-C的MRR中是比较普遍的问题
  • 从理论上讲,内存泄漏是由对象或者变量没有释放引起的,但实践证明并非所有的未释放的对象或变量都会导致内存泄漏,这与硬件环境和操作系统、系统环境有关
  • 内存泄漏导致我们软件在运行过程中占用越来越多的内存,占有资源却又得不到及时清理,会导致我们程序效率越来越低,反应慢,会影响我们用户体验,失去市场的竞争能力

iOS中查找漏点的工具

  • 在xcode中,共提供两种工具帮助查找泄漏点,
    • 1> Analyze
      • 学名:静态分析工具
      • 查找:可以通过 product -> Analyze 菜单项启动
      • 快捷键 CMD + Shift + b
      • Analyze主要分析一下四种问题
        • 逻辑错误:访问空指针或为初始化的变量等;
        • 内存管理错误:如内存泄漏等;
        • 声明错误:从未使用过的变量
        • Api调用错误:未包含使用库和框架
    • 2> Instruments
      • 学名:动态分析工具
      • 查找:product -> profile 菜单项启动
      • 快捷键 CMD + i
      • 简介:它有很多跟跟踪模块可以动态分析和跟踪内存,CPU和文件系统

两种工具查找漏点版本的介绍

  • 1> 结合使用-思路分析:
    • 先使用Analyze静态分析查找可疑泄漏点,在用Instruments动态分析中的Leaks和Allocations跟踪板块进行动态跟踪分析,确认这些点是否泄漏,或者是否存有新的泄漏点出现等
  • 2>使用 静态检测内存泄漏问题 Analyze
  • 在Analyze静态分析结果中,凡是有图标出现的行都是工具发现的疑似泄漏点


    疑似泄漏点所在行.png
  • 点击疑似泄漏点行末尾的分叉图标,会展开分析结果


    展开分析结果.png
  • 检测完成时的效果图如下:


    分析效果图.png
  • 小结:
    • 这里使用Analyze静态分析查找出来的泄漏点,称之为“可疑泄漏点”,之所以称之为“可疑泄漏点”,是因为这些点未必一定泄漏,确认这些点是否泄漏,还要通过Instruments动态分析工具的Leaks和Allocations跟踪模版,Analyze静态分析只是一个理论上的预测过程
  • 3> 动态监测Instruments的Leaks
    • 1)CMD + i 打开
      CMD打开.png
    • 2)打开页面的介绍:


      界面介绍.png
    • 在instruments中,虽然选择了Leaks模版,但默认情况下也会添加Allocations模版,基本上凡是内存分析都会使用Allocations模版,它可以监控内存分布情况
      • a. 选中Allocations模版,(图1区域),右边的3区域会显示随着十斤啊的变化内存使用的折线图,同时在4区域会显示内存使用的详细信息,以及对象分配情况
      • b. 点击Leaks模版(图中2区域)可以查看内存泄漏情况。如果在3区域中有红x出现,则有内存泄漏,4区域则会显示泄漏的对象
    • 3)打开Leaks进行监测:
    • 点击泄漏对象可以在(下图)看到它们的内存地址,占用字节,所属框架和响应方法等信息,打开扩展视图,可以看到右边的跟踪堆栈信息


      leaks进行监测.png
    • 4)监测结果的分析:


      监测结果的分析.png
    • 5)Allocations—内存分配版本的介绍
    • Allocations是监测程序运行过程中 内存分配情况的,也需要同时运行着程序。界面情况如下:


      Allocations.png

      Allocations .jpg
    • 双击某一个方法,同样会跳转到代码中,会有每一句代码对应的内存分配情况,根据这些信息,可以对程序里不同代码的内存占用情况有一些认识,并进行针对性优化

具体使用

  • 1>. Allocations纪录了内存分配,用来优化内存使用的
  • 2>. Leaks用来分析内存泄漏。ARC中引起的内存泄漏原因就是引用环

  • 第一步:先选择Leaks和Leaks by Backtrace.这里可以看到那些对象内训泄漏了,泄漏了多少,这个就是简单看看,没有太多调试意义
    监测内存泄漏多少.png
  • 第二步:然后看看Call Tree,因为Call Tree会给我们大概的位置,有时候会给我们精确的位置,不过要看运气了。
    然后,再右面选择Invert Call Tree和Hide System Library
    Call Tree.png
  • 双击上图中的任意一行,就会跳到代码处内存泄漏的地方(事实上,到这步,很多内存泄漏的问题都会被发现),当然也有一些泄漏还是看不出来的
  • 第三步
  • 然后我们选择对ARC调试很有用的一部分Circles & Roots,通过这个我们可以看到详细的ARC引用计数过程。然后,我们看到如下图


    CirCles & Roots.png
    • 小的红色矩形点击可以看出引用计数的详细信息(ARC就是自动引用计数,计数为0,则对象会被释放)
    • 大的红色矩形可以描绘对象引用环的图,这里如果是我们自己的东西,就能看出来哥哥对象的引用
  • 如果这里没有引用环的图,首先我们找一下我们自定义的对象,正常完成任务这个对像就应该释放了,为了确认这个对象有释放,可以重写dealloc方法,在此方法中log释放信号,看看是否被释放
  • 如果这里就是没有释放,我们可以点击这里对象后的箭头详细查看下,这个对象的引用计数变化如图
    • All 代表所有的引用计数变化
    • Unpaired表示那些未成对的变化·· (成对就是Leaks识别出了对应的+1,-1)
    • By Group会把相应的变化分成一组
    • ByTime会按照顺序列出引用计数变化


      详细信息.png

  • 总结:其实大多数问题在双击上文的代码部分就可以解决了,少数问题需要详细的分析ARC引用过程,
  • 建议如果我们未发现表示内存泄漏的红x,但是我们想进一步评估某个对象对于内存的应用,可以看看Allocations模版的折线图,反复执行从 创建对象 -> 销毁对象 这个过程,如果总占用内存数会随之增加,这说明这个对象没有释放,有些时候虽然占用的对象不是很严重,但是也会增加占用内存,因此必须释放这个对象
  • 提示:有些情况下,对象没有释放是无法检测到的,反复监测内存占用也没有明显的增加,这是最好在配置比较低的设备上测试一下。

文章学习路径:关于Instruments-Leaks工具的归纳总结

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,362评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,330评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,247评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,560评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,580评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,569评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,929评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,587评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,840评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,596评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,678评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,366评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,945评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,929评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,165评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,271评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,403评论 2 342

推荐阅读更多精彩内容