iOS内存管理机制
前言
今天学习了IOS中的内存管理机制,其中一些片段是由其他文章搬过来的,我记得有篇文章是这样写到,站在巨人的肩膀上,我只是一个整理者加了一些自己的理解
为什么要学习内存管理
虽然 ARC 帮我们解决了引用计数的大部分问题,一些年轻的 iOS 开发者仍然会做不好内存管理工作。他们甚至不能理解常见的循环引用问题,而这些问题会导致内存泄漏,最终使得应用运行缓慢或者被系统终止进程。
什么是内存管理
官方解释:软件运行时对计算机内存资源的分配和使用的技术。其最主要的目的是如何高效,快速的分配,并且在适当的时候释放和回收内存资源
知识的补充
1、知识内存区分
我们的智能设备都有RAM(运行内存)和ROM(硬盘)。
RAM:内部存储
ROM:外部存储。
而CPU直接访问的是RAM,如果想访问外部存储,则数据须先放到RAM中才能被CPU访问。
2、RAM和ROM的特点和区别
RAM:运行内存,CPU可以直接访问,访问速度快,不能够断电存储(断电会丢失数据–不稳定)
ROM:存储型内存,CPU不可以直接访问,访问速度慢,可以掉电存储–稳定
3、RAM和ROM的协同工作
由于RAM不支持掉电存储,所以App程序一般存储在ROM中。
手机里面使用的ROM基本都是NandFlash(闪存),CPU是不能直接访问的,而是需要 文件系统/驱动程序 将其读到RAM里面,CPU才可以访问的。
内存分区
内存即指的是RAM,可以分为5个区域
- 栈区:由系统管理。地址从高到低分配。大量的局部变量,深递归,函数循环调用都可能耗尽栈内存而造成程序崩溃
- 堆区:需要我们自己管理内存,alloc申请内存release释放内存。创建的对象也都放在这里。 地址是从低到高分配。堆是所有程序共享的内存,当N个这样的内存得不到释放,堆区会被挤爆,程序立马瘫痪。这就是内存泄漏
- 全局区/静态区(staic):全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。程序结束后有系统释放。
- 常量区:常量字符串就是放在这里的,还有const常量。
- 代码区:存放App代码,App程序会拷贝到这里。
区与区之间是不可以联系的哦!
内存分配
我们需要管理的是堆上的内存
- 非OC对象(基础数据类型)存储在栈上
- OC对象存储在堆上
引用计数
通常来说:当创建(alloc)一个对象的实例并在堆上申请内存时,对象的引用计数就为1,在其他对象中需要持有(retain)这个对象时,就需要把该对象的引用计数加1,需要释放一个对象时,就将该对象的引用计数减1,直至对象的引用计数为0,对象的内存会被立刻释放。
很文艺的解释是怎样的呢?
记得在《寻梦环游记》里对于一个人的死亡是这样定义的:当这个这个世界上最后一个人都忘记你时,就迎来了终极死亡。类比于引用计数,就是每有一个人记得你时你的引用计数加1,每有一个人忘记你时,你的引用计数减1,当所有人都忘记你时,你就消失了,也就是从内存中释放了。
如果再深一层,包含我们后面要介绍的ARC中的强引用和弱引用的话,那这个记住的含义就不一样了。强引用就是你挚爱的亲人,朋友等对你比较重要的人记得你,你的引用计数才加1。
而弱引用就是那种路人,一面之缘的人,他们只是对你有一个印象