iOS APP内存泄漏: MLeaksFinder与 Debug

作者: MD5Ryan | 来源:发表于2016-03-10 09:59 被阅读7407次

更新

升级到 Xcode8之后, 这个库好像没有用了, 具体原因也不详细追究了, 因为 Xcode 自带了强大的 Debug Memory Graph, 直接以关系图的形式来告诉你各个对象的持有关系, 以及出现了泄露时会有紫色的小感叹号出现, 不出现也不意味着没有哟, 所以还需要用这个工具时不时看看现有的存活对象中有没有期望之外的.
下面是一些关键步骤的截图:


Debug Memory Graph入口 出现紫色警告意味着泄露了, 但是貌似不太准确 警告导航栏列出了所有的泄露点

如果在警告列表中没有看到任何东西, 先切换到 BuildTime 那里把右下角的警告筛选给关了就会出现了, 个人认为这是 Xcode 的一个 bug...

这里列出了先阶段所有的"存活"对象

选中某个泄露对象后会出现持有和它有关系的对象关系图, 如下:

引用关系图

这个例子说我们的 ViewController 被 block 持有了, 点击红圈里面的展开可以看到更多的信息, 具体过程就不详细讲了, 因为这里给到的信息已经足够详细, 再需要一些耐心就可以找出具体的原因了.

!注意: 不要开着 NSZombie 来检测, 不然你会发现一大票的泄露.

新工具简介就到这边了, 下面的老的MLeaksFinder的内容, 已经过时, 不读也罢...

前言

一般来说, iOS的内存泄露检测大多是通过Instruments里面的Leaks. Leaks里面可以看到某各类有多少个实例, 还会指出一些循环引用的图示和泄露点. 虽然看起来很美好, 但是每次实际使用的时候, 多多少少会出现一些问题, 最让人难以忍受的就是明明泄露了但是没有报警.

为了解决这个问题, 在这里介绍一个MLeaksFinder的开源库, 这个库是代码级别的检测view和viewController是否出现内存泄露的情况. 它的优势是只要引入后不侵入现有代码, 正常跑一遍APP, 如果出现泄露, 将会触发断言打印相关日志提醒我们出现了泄露. 缺点也比较明显了, 就是只能检测view和viewController级别的泄露. 不过一般来说也足够用了, 毕竟这是大头.

github地址:https://github.com/Zepo/MLeaksFinde

原理

MLeaksFinder的原理还是很简单的, 它swizzle了NavigationController的Push和Pop相关方法来管理viewController和view的生命周期, 在你Pop掉viewController的时候, 会执行这么一段代码

__weak id weakSelf = self;
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [weakSelf assertNotDealloc];
    });

3秒后执行 [weakSelf assertNotDealloc]; 如果这个时候view和viewController已经释放了, 那么weakSelf应该为nil, 所以将不会触发断言, 否则将会打印日志, 触发断言.

实际操作

为了验证是否真正出现泄漏的情况, 可以在出现断言的时候, 进入Instruments的Leaks来看查看类实例个数, 反复进入目标页面后可以查看目标类的实例情况,例如:



Persistent是当前的实例个数, 如果发现Pop之后没有减少, 就肯定是泄漏了. 这里也吐槽一下Instrument, 这种情况是检测不出来的.

发现泄漏点是第一步, 后面还要看怎么泄漏, 方法还是有很多的, 可以自己查相关页面的代码, 我的操作步骤一般是:

1). 点击选中一行之后, Category列会出现箭头, 如: ,

2). 进入到实例页面之后, 再选中实例再点击箭头会出现retain和release的时序列表. 这个时候很卡的话建议暂停运行APP
3). 在这个时序表中查看有没有不该retain但是retain了的函数, 一般只需要看那些单独+1 -1的行, 说明这里的retain和release是没有平衡起来的, 除非是系统代码或者有意为之, 否则都会有一些问题.
4). 发现可疑点之后, 双击进入相关代码, 查看泄露情况, 一般是选择泄露比重最大的那一行代码, 然后进行深入分析.
5). 如果你也曾经出现死活都找不到泄露的位置, 那么时候祭出大杀器--注释代码了.

另外, 对于一些view的泄露, 还是要善用一下Xcode自带的功能, 一般我的操作会是跳到UIImageView或者UILabel的泄漏点选中self, 然后在变量区下面点击那个眼睛, 如下图:



看到里面的内容就能大致猜出出现泄漏的地方了, 一般而言, view单独泄漏的情况还是比较少的, 虽然也出现过, 但是总体而言都是viewController的泄漏连带了view的泄漏.

结语

这个简单的库帮助我找到了很多Instruments没有报警的泄漏点, 个人觉得很好用, 而且引入进来就算忘记移出也没关系, 已经用DEBUG宏包裹起来了, 不会影响到发布.
另外, 有没有同学遇到过前端页面用了-webkit-overflow-scrolling:touch导致出现UIWebOverflowScrollView泄露的啊? 求指导解决.

相关文章

  • iOS APP内存泄漏: MLeaksFinder与 Debug

    更新 升级到 Xcode8之后, 这个库好像没有用了, 具体原因也不详细追究了, 因为 Xcode 自带了强大的 ...

  • MLeaksFinder

    MLeaksFinder 是 iOS 平台的自动内存泄漏检测工具,引进 MLeaksFinder 后,就可以在日常...

  • iOS内存泄漏检测-MLeaksFinder学习及使用

    小总结 MLeaksFinder 是 WeRead 团队开源的iOS内存泄漏检测工具,wereadteam博客,G...

  • MLeaksFinder关闭

    项目中用cocopods引入了MLeaksFinder进行内存泄漏的检查,但是打debug包的时候有时候不想去开启...

  • MLeaksFinder

    [TOC] 简介 MLeaksFinder 是WeRead团队开源的一款检测 iOS 内存泄漏的框架,其使用非常简...

  • 使用MLeaksFinder时遇到的坑

    MLeaksFinder是一个很好的IOS内存泄漏检测工具,能够自动地检测UIViewController和UIV...

  • MLeaksFinder 学习笔记

    MLeaksFinder:精准 iOS 内存泄露检测工具 MLeaksFinder 新特性 MLeaksFinde...

  • MLeakerFinder源码分析

    MLeaksFinder是WeRead团队开源的一款检测iOS内存泄漏的框架,其使用只需将文件加入项目中,如果有内...

  • FBRetainCycleDetector遇到NSMapTabl

    自从项目接入了 MLeaksFinder + FBRetainCycleDetector 的内存泄漏检测方案,在收...

  • iOS 三方库

    1.内存泄漏查找MLeaksFinder,http://wereadteam.github.io/2016/02/...

网友评论

  • 0x00chen:楼主我遇到一个问题,换头像的时候会提示UIImagePickerController 内存泄漏,这个该怎么处理 :sob:
    MD5Ryan:@WebersonGao 我这边是对的, 难道是你那边被墙了? 不过这个库已经被 Xcode 自带的功能取代了, 自带的功能比这个强大很多
    62e5d12973b5:https://github.com/Zepo/MLeaksFinder 网址错啦
    MD5Ryan:@究极魔法师 Xcode8出来之后一般都用自带的内存分析工具检测, 叫 Debug Memory Graph, 就在断点前进后退那一排. 点了之后等一段事件就会出来大量的对象, 筛选出UIImagePickerController这个类的对象之后, 找到没被释放的实例, 然后看谁持有了它, 一般来说都是因为 block 的循环引用, 所以你关注一下__NSMallocBlock__这样的对象, 如果存在, 应该就是 block 的问题.
  • ChiHo:刚刚也在找方法解决UIWebOverflowScrollView的问题,找不到好的解决方案只能用最暴力的方法了。。
    - (void)dealloc
    {
    UIView *scrollView = self.webView;
    while ([scrollView.subviews count]) {
    scrollView = scrollView.subviews[0];
    if ([scrollView isMemberOfClass:NSClassFromString(@"UIWebOverflowScrollView")]) {
    [scrollView removeFromSuperview];
    break;
    }
    }
    }
    席列2:有时UIWebBrowserView还有这个泄漏
    MD5Ryan:@ChiHo 这个办法真心是最后一招了, 我觉得可以给苹果提issue
  • 542c8b81e2d4:不询问是否可以转载也就算了,连原文链接都不贴
    7217715f9524:@wg_hjl 他当然确定 因为这篇文章是他们团队的人发的 :smile: http://wereadteam.github.io/2016/02/22/MLeaksFinder/?utm_source=tuicool&utm_medium=referral
    wg689:@bang 大神 你确定人家不是原创? :joy:
    MD5Ryan:@bang 这个是我自己的原创 请问哪里还有?

本文标题:iOS APP内存泄漏: MLeaksFinder与 Debug

本文链接:https://www.haomeiwen.com/subject/tzdtlttx.html