浅谈iOS的内存管理机制、

前言:

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程序会拷贝到这里。
浅谈iOS的内存管理机制、_第1张图片
4、App程序在内存中的运行:

1、当我们点击手机icon启动一个App时(例如微信): 拓展:iOS程序生命周期详解、

  • 操作系统会为微信开辟4G的虚拟内存空间。
  • 操作系统会把存储在ROM里面的微信部分代码copy到上一步开辟的4G内存空间中。
  • CPU可以访问RAM来运行微信程序了。

假设我们下载了一段视频,那么会从Server一点点下载到RAM,然后再从RAM写入到ROM,这样保证关闭微信再次打开时,视频还在。假设隔一段时间,我们要看视频,程序会将它从ROM读到RAM然后解码播放。数据本地化时候,频繁进行数据读取,可能会涉及到性能优化。

浅谈iOS的内存管理机制、_第2张图片

内存管理:

1、为什么要内存管理?为什么Object-C对象需要进行内存管理?而其它非对象类型比如基本数据类型就不需要进行内存管理呢?

移动设备或者PC设备的内存大小是有限制。
因为OC的对象在内存中是以堆的方式分配空间的,堆内存是由我们自己释放的。就是release。
非OC对象一般是放在栈中,系统会自动回收。

2、什么行为会增加APP的内存占用?
  • 1、定义一个变量、
  • 2、创建一个oc对象、
  • 3、调用一个函数或者方法、
3、Object-C如何进行内存管理:ARC && MRC
  • OC中每个对象都有一个与之对应的整数,叫“引用计数器”。
  • Objective-C的内存管理本质是通过引用计数实现的!!!
  • MRC:在iOS5之前内存是由开发者自己手动管理的,写完代码需要合理插入retainrelease,保证内存不会泄露,程序可以正常运行。
  • ARC:2011年WWDC大会iOS5提出了自动引用计数(ARC),内存的管理由系统进行接管,开发者只需要关注业务逻辑实现,大大提高了开发效率。
4、什么是引用计数?
  • 引用计数(Reference counting)是一个简单有效管理对象生命周期的方式。
  • 当我们新建一个新对象时候,它的引用计数+1,当一个新指针指向该对象,将引用计数+1。当指针不再指向这个对象时候,引用计数-1,当引用计数为0时,说明该对象不再被任何指针引用,将对象销毁,进而回收内存。
浅谈iOS的内存管理机制、_第3张图片

相关面试题

僵尸对象、野指针、空指针分别指什么,有什么区别?
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有什么区别?

你可能感兴趣的:(浅谈iOS的内存管理机制、)