iOS面试题:常见的内存泄漏有哪些情况?如何排查和避免?
面试题:常见的内存泄漏有哪些情况?如何排查和避免?
内存泄漏原理:在百度上的解释就是“程序中已动态分配的堆内存由于某种原因程序未释放或无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃等严重后果”。
-
常见的内存泄漏情况:
-
情况一:对象之间的循环引用问题 循环引用的实质:多个对象相互之间有强引用,不能施放让系统回收。解决办法:使用
weak
打破对象之间的相互强引用 -
情况二:block的循环引用
block
在copy
时都会对block
内部用到的对象进行强引用的。解决办法使用:使用__weak
打破循环的方法只在ARC
下才有效,在MRC
下应该使用__block
-
__weak typeof(self) weakSelf = self; self.myBlock = ^() { // 除了下面的还有 调用 self的一些属性等等 [weakSelf doSomething] };
- 情况三: delegate 的循环引用
delegate
是委托模式.委托模式是将一件属于委托者做的事情,交给另外一个被委托者来处理,在这里我们可能会出现委托者和被委托人之间的相互强引用问题;解决办法:在声明delegate
属性的时候 用weak
进行弱引用 或者 通过中间对象(代理对象)的方式来解决(效率更加高的中间对象NSProxy:
不需要进行发送消息和再动态解析,直接进行消息转发)
@property(nonatomic, weak) id delegate;
-
情况四:
CADisplayLink
、NSTimer
会对target
产生强引用,如果target
又对它们产生强引用,那么就会引发循环引用;解决办法:NSTimer
有一个block
的方法,我们可以利用block
的弱指针来解决__weak typeof(self) weakSelf = self;
传weakSelf
进去 -
情况五:通知的循环引用
iOS9
以后,一般的通知,都不再需要手动移除观察者,系统会自动在dealloc
的时候调用[[NSNotificationCenter defaultCenter] removeObserver: self]
。iOS9
以前的需要手动进行移除。原因是:iOS9
以前观察者注册时,通知中心并不会对观察者对象做retain
操作,而是进行了unsafe_unretained
引用,所以在观察者被回收的时候,如果不对通知进行手动移除,那么指针指向被回收的内存区域就会成为野指针,这时再发送通知,便会造成程序崩溃。从iOS9
开始通知中心会对观察者进行weak
弱引用,这时即使不对通知进行手动移除,指针也会在观察者被回收后自动置空,这时再发送通知,向空指针发送消息是不会有问题的。建议最好加上移除通知的操作:
(void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self.observer name:@"name" object:nil]; }
- 情况六:
WKWebView
造成的内存泄漏 总的来说,WKWebView
不管是性能还是功能,都要比UIWebView
强大很多,本身也不存在内存泄漏问题,但是,如果开发者使用不当,还是会造成内存泄漏。请看下面这段代码:
@property (nonatomic, strong) WKWebView *wkWebView; * (void)webviewMemoryLeak { WKWebViewConfiguration *config =[[WKWebViewConfiguration alloc] init]; config.userContentController = [[WKUserContentController alloc] init]; [config.userContentController addScriptMessageHandler:self name:@"WKWebViewHandler"]; _wkWebView = [[WKWebView alloc] initWithFrame:self.view.bounds configuration:config]; _wkWebView.backgroundColor = [UIColor whiteColor]; [self.view addSubview:_wkWebView]; NSURLRequest *requset = [NSURLRequest requestWithURL:[NSURL URLWithString:@"[https://www.baidu.com](https://www.baidu.com/)"]]; [_wkWebView loadRequest:requset]; } 这样看起来没有问题,但是其实 “addScriptMessageHandler” 这个操作,导致了 wkWebView 对 self 进行了强引用,然后 “addSubview”这个操作,也让 self 对 wkWebView 进行了强引用,这就造成了循环引用。解决方法就是在合适的机会里对 “MessageHandler” 进行移除操作: * (void)viewDidDisappear:(BOOL)animated { [super viewDidDisappear:animated]; [_wkWebView.configuration.userContentController removeScriptMessageHandlerForName:@"WKWebViewHandler"]; }
-
内存泄漏的查询
-
第一种查询方式:
Analyze
静态分析 (command + shift + b
)也就是编译,主要分析以下四种问题:- 逻辑错误:访问空指针或未初始化的变量等;
- 内存管理错误:如内存泄漏等;
- 声明错误:从未使用过的变量;
Api
调用错误:未包含使用的库和框架。
-
第二种查询方式:
Instruments
中的Leak
动态分析内存泄漏,product->profile ->leaks
打开工具主窗口 -
第三种:
Facebook
早已开源了一款检测内存问题的三方库FBRetainCycleDetector
更多:iOS面试题 答案合集 更多:《BAT面试答案文集.PDF》,获取可加iOS技术交流圈:937194184,相互交流。

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
高并发,你真的了解吗?
摘要:本文介绍高并发系统的度量指标,讲述高并发系统的设计思路,再梳理高并发的关键技术,最后结合作者的经验做一些延伸探讨。 当前,数字化在给企业带来业务创新,推动企业高速发展的同时,也给企业的IT软件系统带来了严峻的挑战。面对流量高峰,不同的企业是如何通过技术手段解决高并发难题的呢? 0、引言 软件系统有三个追求:高性能、高并发、高可用,俗称三高。三者既有区别也有联系,门门道道很多,全面讨论需要三天三夜,本篇讨论高并发。 高并发(High Concurrency)。并发是操作系统领域的一个概念,指的是一段时间内多任务流交替执行的现象,后来这个概念被泛化,高并发用来指大流量、高请求的业务情景,比如春运抢票,电商双十一,秒杀大促等场景。 很多程序员每天忙着搬砖,平时接触不到高并发,哪天受不了跑去面试,还常常会被面试官犀利的高并发问题直接KO,其实吧,高并发系统也不高深,我保证任何一个智商在线的看过这篇文章后,都能战胜恐惧,重拾生活的信心。 本文先介绍高并发系统的度量指标,然后讲述高并发系统的设计思路,再梳理高并发的关键技术,最后结合作者的经验做一些延伸探讨。 1、高并发的度量指标 既然是高并...
- 下一篇
美图运维之旅:在阿里云上的经验以及踩过的坑
前言 美图公司是如何使用阿里云的 我们是如何做成本优化的 我们在阿里云上遇到了哪些坑 我们如何做自动化运维的 前言 本篇文章可能更多的是文字表述,没啥高深的用词,都是大白话,需要各位朋友有耐性的阅读下去,也希望各位朋友能够提出宝贵建议。 美图公司是如何使用阿里云的 关于使用方面,我想从以下几个点简单叙述一下, 权限规划 区域规划 网络规划 型号规划 统一登录规划 命名规划 权限规划 权限规划只要是在账号权限规划上,一般是主账号+子账号,然后通过ram来进行对应授权,为什么要做这个,因为主账号一般控制在运维手上,子账号可能会存在其他运维手上以及某些开发手上,那么就需要做严格的权限控制。目前阿里云ram有几个点:用户,群组,角色,策略等功能,目前角色和策略都支持自定义,然后可以应用到用户上,群组上。角色可以附加到ecs上,可以用高权限获取一些云上资源信息。 区域规划 做区域规划需要考虑几点: 第一、你的业务架构,比如我有idc机房在北京,那么我们上云的话一般会考虑北京region,又比如我的业务用户主要分布在江浙一带,那么我们一般就考虑上海或者杭州region。 第二、一定要找阿里云技术问...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Linux系统CentOS6、CentOS7手动修改IP地址
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- CentOS关闭SELinux安全模块
- 2048小游戏-低调大师作品
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16
- 设置Eclipse缩进为4个空格,增强代码规范
- CentOS8安装MyCat,轻松搞定数据库的读写分离、垂直分库、水平分库
- Docker快速安装Oracle11G,搭建oracle11g学习环境