前言:
15年参加工作时的时候已经是ARC的天下了。当初用的最早的Xocde是5.1版本,所以对于内存管理在项目之中没有亲身经历,但是项目这么久了,隐隐约约也能感受到苹果ARC的魅力。
知识补充:
我们首先先了解一些计算机的基本知识。
1、硬件内存区分:
我们的手机、电脑、或者智能设备都有
RAM
(运行内存)和ROM
(硬盘)。
RAM是内部存储,ROM是外部存储。我们的CPU直接访问的是RAM,如果想访问外部存储,则数据须先放到RAM中才能被CPU访问。CPU
不能直接从内存卡
里面读取指令(需要Flash驱动等等)
2、RAM和ROM的特点和区别:
RAM:运行内存,CPU可以直接访问,访问速度快,价格高,不能够掉电存储-断电会失去数据-不稳定。
ROM:存储型内存,CPU不可以直接访问,访问速度慢,价格低,可以掉电存储-稳定。
3、RAM和ROM的协同工作:
由于RAM不支持掉电存储,所以App程序一般存储在ROM中。
手机里面使用的ROM基本都是NandFlash(闪存)
,CPU是不能直接访问的,而是需要文件系统/驱动程序(嵌入式中的EMC)
将其读到RAM里面,CPU才可以访问。另外,RAM的速度也比NandFlash快。
3、内存分区:
说到内存分区,内存即指的是RAM,可以分为5个区。
栈区(heap
):由系统去管理。地址从高到低分配。先进后出。会存一些局部变量,函数跳转跳转时现场保护(寄存器值保存于恢复),这些系统都会帮我们自动实现,无需我们干预。所以大量的局部变量,深递归,函数循环调用都可能耗尽栈内存而造成程序崩溃 。堆区(stack)
:需要我们自己管理内存,alloc申请内存release释放内存。创建的对象也都放在这里。 地址是从低到高分配。堆是所有程序共享的内存,当N个这样的内存得不到释放,堆区会被挤爆,程序立马瘫痪。这就是内存泄漏。全局区/静态区(staic)
:全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。程序结束后有系统释放。常量区
:常量字符串就是放在这里的,还有const常量。代码区
:存放App代码,App程序会拷贝到这里。
4、App程序在内存中的运行:
1、当我们点击手机icon启动一个App时(例如微信): 拓展:iOS程序生命周期详解、
- 操作系统会为微信开辟4G的虚拟内存空间。
- 操作系统会把存储在ROM里面的微信部分代码copy到上一步开辟的4G内存空间中。
- CPU可以访问RAM来运行微信程序了。
假设我们下载了一段视频,那么会从Server一点点下载到RAM,然后再从RAM写入到ROM,这样保证关闭微信再次打开时,视频还在。假设隔一段时间,我们要看视频,程序会将它从ROM读到RAM然后解码播放。数据本地化时候,频繁进行数据读取,可能会涉及到性能优化。
内存管理:
1、为什么要内存管理?为什么Object-C对象需要进行内存管理?而其它非对象类型比如基本数据类型就不需要进行内存管理呢?
移动设备或者PC设备的内存大小是有限制。
因为OC的对象在内存中是以堆的方式分配空间的,堆内存是由我们自己释放的。就是release。
非OC对象一般是放在栈中,系统会自动回收。
2、什么行为会增加APP的内存占用?
- 1、定义一个变量、
- 2、创建一个oc对象、
- 3、调用一个函数或者方法、
3、Object-C如何进行内存管理:ARC && MRC
- OC中每个对象都有一个与之对应的整数,叫“
引用计数器
”。 - Objective-C的内存管理
本质
是通过引用计数实现的!!! - MRC:在iOS5之前内存是由开发者自己手动管理的,写完代码需要合理插入
retain
和release
,保证内存不会泄露,程序可以正常运行。 - ARC:2011年WWDC大会iOS5提出了自动引用计数(ARC),内存的管理由系统进行接管,开发者只需要关注业务逻辑实现,大大提高了开发效率。
4、什么是引用计数?
- 引用计数(Reference counting)是一个简单有效管理对象生命周期的方式。
- 当我们新建一个新对象时候,它的引用计数+1,当一个新指针指向该对象,将引用计数+1。当指针不再指向这个对象时候,引用计数-1,当引用计数为0时,说明该对象不再被任何指针引用,将对象销毁,进而回收内存。
相关面试题
僵尸对象、野指针、空指针分别指什么,有什么区别?
Objective-C有GC(垃圾回收机制)吗?
如果一个对象释放前被加到了NotificationCenter中,不在NotificationCenter中remove这个对象可能会出现什么问题?
为什么很多内置的类,如TableViewController的delegate的属性是assign不是retain?
内存管理的几条原则是什么?按照默认法则,哪些关键字生成的对象需要手动释放?哪些对象不需要手动释放会自动进入释放池?在和property结合的时候怎样有效的避免内存泄露?
在block内如何修改block外部变量?
使用block时什么情况会发生引用循环,如何解决?
retain、release和autorelease的底层实现
Objective-C是如何实现内存管理的?autorealease pool自动释放池是什么?autorelease的对象是在什么时候被release的?autorelease和release有什么区别?
网友评论