iOS开发中的内存管理相关

来源:互联网 发布:java工作一年没提高 编辑:程序博客网 时间:2024/05/22 17:00

自iOS5以后,内存管理使用ARC,先来说下ARC
1> ARC:ARC是“由编译器进行内存管理”的,比如它自动管理retain和release的过程,ARC会在底层来做这些操作,而不用手动再去管理;而实际上只有编译器是无法完全胜任的,在此基础上还需要Objective-C运行时库的协助也就是说ARC由(1)clang(LLVM编译器)3.0以上 和 (2)objc4 Objective-C运行时库493.9以上 来实现的
2>联系之前使用的MRC,需要时刻注意,如果需要持有一个对象,那么对其发送retain,如果之后不再使用该对象,那么需要对其发送release(或者autorelease),每一次对retain,alloc或者new的调用,需要对应一次release或者autorelease调用,但是有时候总避免不了忘记对对象执行release操作或者重复release,导致内存泄漏或者过多释放
3> ARC相比MRC优势:为了更好的进行内存管理,ARC作为OC编译器的特性,能够在编译时自动在合适的位置插入release或autorelease,相比较MRC而言,ARC完成了在最合适的地方对引用计数的维护,以及部分优化,使得ARC比MRC有更高的运行效率
4> ARC也有缺点:ARC并不能够排除所有内存泄漏的可能性,因为ARC只能用在OC对象上,当涉及到较为底层的东西,比如CoreFoundation Object时,需要手动进行内存管理,总之,当创建一个对象时,必须清楚的知道谁拥有该对象,并清楚持有者在什么时候应该变为nil

针对ARC开发的应用,如果使用到MRC有关的项目文件,该如何解决
在开发ARC相关的应用时,当遇到使用到MRC有关的项目文件时,比如在ARC项目中使用到了MRC的第三方框架(如ASIHttpRequest),此时的解决方法为:
1)选择targets,然后选择build phases标签
2)展开compile sources
3)在所有ASIHttpRequest相关的文件后面的Compiler Flags中加入编译选项:-fno-objc-arc

针对内存泄漏,在开发项目中使用哪些办法来避免
1>通过静态分析:Analyze
2>通过instruments:Profile,通过Analyze不能把所有的内存泄漏查出来,有的内存泄漏是在运行时,用户操作时才产生,这个时候使用instruments的leaks工具
3>通过内存猛增检测工具:Allocations,Allocations工具可以很容易列出所有分配内存的点,这样可以按照分配内存大小来排序,发现哪些点分配的内存最多
4>通过代码测试:init和dealloc是否会被成对触发

针对内存管理,有没有遇到内存暴增的时候
1>当在列表滑动的时候内存莫名增长,
2>频繁访问图片的时候内存莫名增长,
3>频繁的打开和关闭数据库的时候内存莫名的增长……
这些都是基于autorelease机制所引起。分析:
1>滑动列表的时候,内存出现莫名的增长:
1)没有使用UITableView的reuse机制,导致每显示一个cell都用autorelease的方式重新alloc一次,导 致cell的内存不断的增加
2)每个cell会显示一个单独的UIView,在UIView发生内存泄漏,导致cell的内存不断增长
2>频繁访问图片的时候,内存莫名的增长:
频繁的访问网络图片,导致iOS内部API会不断的分配autorelease方式的buffer来处理图片的解码与显示,利用图片cache可以缓解此问题
3>频繁打开和关闭SQLite,导致内存不断的增长:
在进行SQLite频繁打来和关闭操作,而且读写的数据buffer较大,那么SQLite在每次打开与关闭的时候,否会利用autorelease的方式分配512k的内存;如果访问次数很多,内存马上就会达到几十兆,甚至上百兆,所以针对频繁的读写数据库buffer较大的情况,可以设置SQLite的长连接方式,避免频繁的打开和关闭数据库

简单介绍一下自动释放池
概念:NSAutoreleasePool内部包含一个数组NSMutableArray,用来保存声明为
如果一个对象声明为autorelease,系统所做的工作就是把这个对象加入到这个数组中。
NSAutoreleasePool自身在销毁的时候,会遍历一遍这个数组,release数组中的每个成员。

自动释放池的手动创建和自动创建
1>需要手动创建自动释放池—

如果正在编写一个不是基于Application Kit的程序,比如命令行工具,则没有对自动释放池的内置支持,需要手动创建;
如果生成了一个从属线程,则一旦该线程开始执行,必须立即创建自动释放池,否则,就会泄漏对象;
如果编写了一个循环,其中创建了许多的临时对象,可以在循环内部创建一个自动释放池,以便在下次迭代之前销毁这些对象,帮助减少应用程序的最大内存占用量。
2>系统自动创建自动释放池—
Application Kit会在一个事件周期(或事件循环迭代)的开端,比如鼠标按下事件,自动创建一个自动释放池,并且在事件周期的结尾释放它

0 0