二、内存相关

注:本文集为自己准备面试时,系统复习的笔记,如大家有兴趣,欢迎阅读并指正
1.autoreleaspool有什么用,什么时候创建,什么时候释放?
2.__strong、__weak、assign的修饰符的底层实现,引用计数器的位置?
3.什么是消息转发和消息查找?如何捕捉崩溃?
4.分类为什么没有属性?分类和扩展区别,为什么分类不可以添加属性,扩展可以?

1、内存布局
  • 代码区:程序代码
  • 全局区:未初始化及已初始化。
  • 堆区:低地址到高地址
  • 栈区:高地址到低地址
2、内存管理方案
  • TaggedPointer:小对象管理
  • NONPOINTER_ISA:非指针性的isa指针
    arm64架构:64个比特位。
    • 第一位:是否是纯指针,如果否表示含有引用技术表
    • 第二位:是否有关联对象
    • 第三位:表示是否含有c++的内容
    • 第4位-第37位:当前位的类对象指针地址
    • 第42位:弱引用表
    • 第43位:是否正在deallocating操作
    • 第44位:散列表
    • extra_rc:存储<10的引用计数器
  • 散列表(引用计数表和弱引用表)
    1. Slide Tables(): 包含Slide Table的数组,为哈希表,
    2. Slide Table:包含spinlock_t(自旋锁)、RefcountMap(引用计数表)、weak_table_t(弱引用表)
    3. 为什么不是一个Slide Table而是Tables?
      存在改变对象有读写安全问题,读写安全需要加锁,因此为提高效率分成多个table。
ps:散列表本质就是一张哈希表,实现快速分流,什么是哈希表?

ptr->f(ptr) ->index

3、数据结构

Spinlock_t

  • spinlock_t是“忙等”的锁,适用于轻量访问
  • 自旋锁和普通的锁有什么区别?适用于哪些场景?

RefcountMap:引用技术表,哈希表。适用哈希为了提高查找效率
weak_table_t:弱引用表。key:对象指针、value:weak修饰的指针

4、MRC和ARC

MRC:手动引用计数。
ARC:是LLVM和Runtime协作的结果。禁止手动调用retain/release/retainCount/dealloc

5、引用计数管理

dealloc释放过程:
dealloc方法实现如下图


image.png

判断是否是pointer_isa,weak表,关联对象,c++,slidtable表是否释放

object_dispose()方法实现如下图


image.png
6、弱引用原理
  • 声明
    __weak声明的指针,经过编译器声明,会调用objc_initWeak()方法继续调用storeWeak()方法,最后会调用weak_register_no_lock()方法进行弱引用变量添加,具体添加的位置是通过哈希算法查找到index,如果存在,添加到原有的数组中,如果没有创建弱引用数组,index=0存放改指针。
  • 清除
    weak_clear_no_lock()。当一个对象dealloc,dealloc方法中会对weak清除的函数,会根据当前对象指针查找弱引用表,把当前对象相对应的引用都拿出来数组,并把当前数组所有指针置为nil。
7.自动释放池
  1. AutoreleasePool的实现原理是怎样的?
  2. AutoreleasePool为何可以嵌套使用?
@autoreleasepool{}
// => 等价于
void *ctx = objc_autoreleasePoolPush();
{}
objc_autoreleasePoolPop(ctx);

什么是自动释放池?

  • 以栈为结点通过双向链表的形式组合而成的数据结构,是和线程一一对应
    自动释放池什么时候创建,什么时候销毁?
8、循环引用?
  • 自循环引用
  • 相互循环引用,__block可以使用循环引用?
  • 多循环引用

是否在开发过程中碰到循环引用问题,你是怎么解决的?
Block循环引用

NSTimer循环引用

你可能感兴趣的:(二、内存相关)