随着项目的业务逻辑的增多,难免会出现一些性能问题,今天要讨论的问题就是平时不太注意感觉影响也不大,但一旦对应用产生影响,那么后果非常严重,会导致应用很容易崩溃,这个问题就是内存泄漏问题.
什么是内存泄漏?什么是内存溢出?
- 内存泄露( memory leak):是指程序在申请内存后,无法释放已申请的内存空间,一次内存泄露危害可以忽略,但内存泄露堆积后果很严重,无论多少内存,迟早会被占光。
- 内存泄露( memory leak):是指程序在申请内存后,无法释放已申请的内存空间,一次内存泄露危害可以忽略,但内存泄露堆积后果很严重,无论多少内存,迟早会被占光。
如何排查内存泄漏问题?
常用的内存泄漏的排查方法有两种:静态分析方法(Analyze)和动态分析方法(Instrument的leak)。
1.静态内存泄漏分析方法:
首先通过xcode打开项目,点击Product,在下拉菜单中点击Analyze就可以进行静态内存泄漏分析.如下图:
image.png
分析出如下图所示的内存泄漏:
image.png
静态分析方法只能分析出大部分问题,但是还有一部分问题需要通过动态分析方法来分析,下面我们用动态内存分析方法进行更加全面的分析需要用到instrument中的leaks,具体操作是通过xcode打开项目,然后点击product-->profile.
image.png
image.png
选中leads->点击Choose打开如下图页面:
image.png
点击左上角红圈,这是项目开始运行,由于leaks是动态监测,所以手动进行一系列操作,可检查项目中是否存在内存泄漏问题.出现红X表示出现内存泄漏.
image.png
选择CallTree,并且在右下角勾选Invert Call Tree 和Hide System Libraries,会发现显示若干行代码,双击即可跳转到出现内存泄漏的地方,修改即可.
常见的导致内存泄漏的原因
现在的主要开发模式是以ARC进行的内存管理,导致内存泄漏的根本原因是代码中存在循环引用,从而导致一些内存无法释放,这就会导致dealloc()方法无法被调用。
导致循环引用的几种类型如下:
1.控制器(ViewController)中使用了NSTimer.
[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(updateTime:) userInfo:nil repeats:YES];
使用这个方法时 target:self 会使ViewController的count+1,如果你不用使用invalidate,控制器不会执行dealloc,不会被销毁
2.ViewController中引入代理delegate
如果控制器中引入代理并且通过Delegate+protocol的方式传参数给其他对象,那么这个delegate一定不要强引用,尽量assign或者weak,否则你的VC会持续持有这个delegate,直到它自身被释放。
3.ViewController中使用Block
block为了保证代码块内部对象不被提前释放,会对block中的对象进行强引用,就相当于持有了其中的对象,而如果此时block中的对象又持有了该block,就会造成循环引用.
网友评论