前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >iOS开发中内存泄漏检测工具--MLeaksFinder

iOS开发中内存泄漏检测工具--MLeaksFinder

作者头像
用户1451823
发布2018-09-13 15:40:04
2.1K0
发布2018-09-13 15:40:04
举报
文章被收录于专栏:DannyHoo的专栏DannyHoo的专栏

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://cloud.tencent.com/developer/article/1337757

在iOS 开发过程中我们有时会遇到内存泄漏的问题,我们也会对内存泄漏进行监测,如苹果自带的Instrument。我们会使用Instrument中的Leaks/Allocations对内存泄漏进行监测,但在使用过程中却会存在各种问题以及不便。

leaks的问题:

其中 Leaked memory 和 Abandoned memory 都属于应该释放而没释放的内存,都是内存泄露,而 Leaks 工具只负责检测 Leaked memory,而不管 Abandoned memory。在 MRC 时代 Leaked memory 很常见,因为很容易忘了调用 release,但在 ARC 时代更常见的内存泄露是循环引用导致的 Abandoned memory,Leaks 工具查不出这类内存泄露,应用有限。

Allocations的问题:

对于 Abandoned memory,可以用 Instrument 的 Allocations 检测出来。检测方法是用 Mark Generation 的方式,当你每次点击 Mark Generation 时,Allocations 会生成当前 App 的内存快照,而且 Allocations 会记录从上回内存快照到这次内存快照这个时间段内,新分配的内存信息。举一个最简单的例子:

我们可以不断重复 push 和 pop 同一个 UIViewController,理论上来说,push 之前跟 pop 之后,app 会回到相同的状态。因此,在 push 过程中新分配的内存,在 pop 之后应该被 dealloc 掉,除了前几次 push 可能有预热数据和 cache 数据的情况。如果在数次 push 跟 pop 之后,内存还不断增长,则有内存泄露。因此,我们在每回 push 之前跟 pop 之后,都 Mark Generation 一下,以此观察内存是不是无限制增长。这个方法在 WWDC 的视频里: Session 311 - Advanced Memory Analysis with Instruments ,以及苹果的开发者文档: Finding Abandoned Memory 里有介绍。

用这种方法来发现内存泄露还是很不方便的:

首先,你得打开 Allocations

其次,你得一个个场景去重复的操作

无法及时得知泄露,得专门做一遍上述操作,十分繁琐

之前在项目中就使用了一个更好的监测内存泄漏的工具,可一直没有记录下来,这次有时间就赶紧记录在此。这个工具的名字是MLeaksFinder。先附上MLeaksFinder的下载地址:https://github.com/Zepo/MLeaksFinder

我们只要将MLeaksFinder导入到项目中就能监测项目中的内存泄漏的代码了,而无需我们做更多的操作。MLeaksFinder只在debug模式下有效,而不会影响我们的release包。当程序出现内存泄漏,会弹出一个内存泄漏的提示框,并显示是谁发生了内存泄漏,如图所示:

这样我们就能很快地定位到内存泄漏的页面了。

MLeaksFinder的原理:

MLeaksFinder一开始是从UIViewController入手的,UIViewController在POP或dismiss之后该控制器及其上的view,view的subviews都会被释放掉,MleaksFinder就是在控制器POP或dismiss之后去查看该控制器和其上的view是否都被释放掉。

具体的方法是,为基类 NSObject 添加一个方法 -willDealloc 方法,该方法的作用是,先用一个弱指针指向 self,并在一小段时间(3秒)后,通过这个弱指针调用 -assertNotDealloc,而 -assertNotDealloc 主要作用是直接中断言。这样,当我们认为某个对象应该要被释放了,在释放前调用这个方法,如果3秒后它被释放成功,weakSelf 就指向 nil,不会调用到 -assertNotDealloc 方法,也就不会中断言,如果它没被释放(泄露了),-assertNotDealloc 就会被调用中断言。这样,当一个 UIViewController 被 pop 或 dismiss 时(我们认为它应该要被释放了),我们遍历该 UIViewController 上的所有 view,依次调 -willDealloc,若3秒后没被释放,就会中断言。

简而言之就是当一个对象3秒之后还没释放,那么指向它的 weak 指针还是存在的,所以可以调用其 runtime 绑定的方法 willDealloc 从而提示内存泄漏。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017年06月07日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档