iOS-内存管理objective-c

iOS面试 -- 内存管理

2020-03-16  本文已影响0人  一意孤行的程序猿

来源:爱玩游戏的iOS菜鸟

内存布局

iOS程序下内存布局

不同内存布局区域的含义
stack(栈):方法调用
heap(堆):通过alloc等分配的对象
bss:未初始化的全局变量
data:已初始化的全局变量
text:程序代码

内存管理方案

散列表

散列表中数据结构

ARC&&MRC

  1. MRC 手动引用计数
    • alloc
    • retain
    • release
    • retainCount
    • autorelease
    • dealloc

2.ARC 自动引用计数

引用计数

dealloc实现流程

判断时候可以释放的条件(五个条件缺一不可)
*   没有使用nonpointer_isa
*   没有weak指针指向
*   没有有关联对象
*   没有使用ARC或者涉及C++
*   当前对象的引用计数没有通过SideTable中的引用计数表来存储的

object_dospose()函数内部实现分析

clearDeallocating()内部实现

clearDeallocating()内部实现

弱引用

weak变量的添加过程

如何添加weak变量的?
对象指针在经过编译器的编译之后调用objc_initweak(),然后storeweak()方法,经过一系列的函数调用,最终在weak_register_no_lock()进行弱引用变量的添加,通过hash算法位置查找,如果已经存在当前对象对应的弱引用数组,则直接加进去,如果没有则创建新个新的弱引用数组,存放新的weak指针

系统如何实现将废弃的weak指针置为nil

系统如何实现将废弃的weak指针置为nil?
当对象被dealloc后废弃之后,会调用弱引用清除的相关函数。然后在函数实现中,根据当前对象指针,查找弱引用表,把当前对象对应的弱引用都拿出来,然后遍历所有的弱引用指针置为nil

自动释放池

AutoreleasePool的实现原理是怎么样的?

AutoreleasePool是以栈为结点,通过双向链表的形式组合而成的数据结构。编译器会将@autoreleasepool{}改写,如下 图。实际objc_autoreleasePoolPop函数在内部做了pop操作,批量将autoreleasepool中的所有的对象都会做一次release操作

编译器改写@autoreleasepool{}

下面对上面的主要函数进行一个简单的说明

AutoreleasePool的结构

什么是双向链表?

双向 链表结构

[obj autorelease]的实现(对象加入自动释放池)

先判断当前next指针是否指向栈顶,如果不是直接加入;如果是,则增加一个栈结点到链表上,在新的栈添加对象;移动next指针

AutoreleasePoolPage::push实现流程(释放池多层嵌套)
AutoreleasePoolPage::pop实现流程(与push相反)
AutoreleasePool为何可以嵌套使用?

多次插入哨兵对象,也就是对一个新的releasePool的创建,如果当前栈没有满,则不需要创建新的page,如果满了,新增一个栈节点

下面这个图中,array对象在什么时候释放呢?

答:在档次runloop将要结束的时候调用AutoreleasePoolPage:pop(),对array对象执行release操作

AutoreleasePool的使用场景?

在for循环中,alloc图片数据等内存消耗较大的场景手动插入autoreleasePool,每一次for循环都进行一次内存的释放,降低内存消耗

循环引用

常见的循环引用以及破除方法:
如何破除循环引用?
具体解决方案有哪些?
__block在ARC和MRC条件下的区别
__unsafe_unretained破解
循环引用的示例?(平时开发时是否有遇到循环引用,又是怎么解决的?)
  1. Block使用示例(在后面block讲解时)
  2. NSTimerd的循环引用问题

作为一个开发者,有一个学习的氛围跟一个交流圈子特别重要,这是一个我的点击加入群聊iOS交流群:789143298 进群密码123,不管你是小白还是大牛欢迎入驻 ,分享BAT,阿里面试题、面试经验,讨论技术, 大家一起交流学习成长!

上一篇下一篇

猜你喜欢

热点阅读