目录:
1、内存的定义
2、内存管理的基础概念
3、IOS系统中的内存管理
1、内存的定义
1.1. 内存是计算机中重要的部件之一,它是与CPU进行沟通的桥梁。
1.2. 计算机中所有程序的运行都是在内存中进行的,因此内存的性能对计算机的影响非常大。
1.3. 内存(Memory)也被称为内存储器,其作用是用于暂时存放CPU中的运算数据,以及与硬盘等外部存储器交换的数据。
1.4. 只要计算机在运行中,CPU就会把需要运算的数据调到内存中进行运算,当运算完成后CPU再将结果传送出来,内存的运行也决定了计算机的稳定运行。
1.5. 内存是由内存芯片、电路板、金手指等部分组成的。
2、内存管理的基础概念
2.1 常见的内存问题:
1)内存泄漏:是指程序在申请的内存空间使用完毕之后未回收。影响:若内存泄漏一致存在,无论有多少内存,迟早都会被占用光,最终导致程序crash。(因此,开发中我们要尽量避免内存泄漏的出现)
2)内存溢出:是指程序在申请内存时,没有足够的内存空间供其使用。 通俗理解就是内存不够用了,通常在运行大型应用或游戏时,应用或游戏所需要的内存远远超出了你主机内安装的内存所承受大小,就叫内存溢出。最终导致机器重启或者程序crash。
3)提前释放;4)重复释放。
2.2 内存管理的定义、以及意义:内存管理是指软件运行时对计算机内存资源的分配和使用的技术。其最主要的目的是如何高效,快速的分配,并且在适当的时候释放和回收内存资源。
3、IOS系统中的内存管理
3.1 引用计数
(引自维基百科)引用计数是计算机编程语言中的一种内存管理技术,是指将资源(可以是对象、内存或磁盘空间等等)的被引用次数保存起来,当被引用次数变为零时就将其释放的过程。使用引用计数技术可以实现自动资源管理的目的。同时引用计数还可以指使用引用计数技术回收未使用资源的垃圾回收算法。
当创建一个对象的实例并在堆上申请内存时,对象的引用计数就为1,在其他对象中需要持有这个对象时,就需要把该对象的引用计数加1,需要释放一个对象时,就将该对象的引用计数减1,直至对象的引用计数为0,对象的内存会被立刻释放。
3.2 tagged Pointer
1)苹果公司在ARM64架构后,推出的一种轻量级存储技术,用于优化NSNumber、NSDate、NSString等小对象的存储。
2)在没有使用Tagged Pointer之前, NSNumber等对象需要动态分配内存、维护引用计数等,NSNumber指针存储的是堆中NSNumber对象的地址值。当指针不够存储数据时,才会使用动态分配内存的方式来存储数据。
3)使用Tagged Pointer之后,NSNumber指针里面存储的数据变成了:Tag + Data,也就是将数据直接存储在了指针中。
3.3 autoreleasePool
1)自动释放池的主要底层数据结构是:__AtAutoreleasePool、AutoreleasePoolPage。
2)在工程中调用了autorelease修饰的对象最终都是通过AutoreleasePoolPage对象来管理的,AutoreleasePoolPage中存储着这些对象的内存地址。
3)AutoreleasePoolPage:
a, 所有的AutoreleasePoolPage对象通过双向链表的形式连接在一起;
b, 每个AutoreleasePoolPage对象占用4096字节内存,除了用来存放它内部的成员变量,剩下的空间用来存放autorelease对象的地址;
c,调用push方法会将一个POOL_BOUNDARY入栈,并且返回其存放的内存地址;调用pop方法时传入一个POOL_BOUNDARY的内存地址,会从最后一个入栈的对象开始发送release消息,直到遇到这个POOL_BOUNDARY。
d, objc_autoreleasePoolPop()、objc_autoreleasePoolPush()调用时机:
iOS在主线程的Runloop中注册了2个Observer:
第1个Observer监听了kCFRunLoopEntry事件,会调用objc_autoreleasePoolPush();
第2个Observer监听了kCFRunLoopBeforeWaiting事件,会调用objc_autoreleasePoolPop()、objc_autoreleasePoolPush()监听了kCFRunLoopBeforeExit事件,会调用objc_autoreleasePoolPop()
3.4 ARC、MRC
ARC: 自引用用计数 (automatic reference counting);
MRC: 手动引用计数(manual reference counting);
详情可以参考这边文章:iOS学习心得之:MRC和ARC简单理解
3.5 深拷贝、浅拷贝
浅拷贝:指针拷贝,仅拷贝一份指向被拷贝对象的指针、指向此对象。
深拷贝:对象拷贝,是对object对象的复制,保留原对象的值,开辟新的内存地址。
OC语法中的mutablecopy表示对修饰对象进行深拷贝操作,copy表示对修饰对象可能是深拷贝也可能是浅拷贝
3.6 属性的修饰词与引用计数,这篇文章写的很清楚。
(PS : 其中有部分章节是从前人的文章中搬运过来整理而成,这些文章里已经对部分知识点解释的很清楚明了了,我也没有更好的表达方式,所以站在巨人的肩膀上,我只是一个整理者加了部分自己的理解。)