面试复习-内存管理

  1. timer displayLink会有循环引用的问题
  • 解决 block+weakSelf,定制timer内部用 NSProxy进行转发,解决依赖
  • Timer 里面有 timer 和 proxy,timer转发给proxy,proxy转发给 realTarget
  1. timer计时器不准确,使用GCD的定时器更加准确
  2. 内存布局从低到高为

保留区 (最低)
代码段 (编译厚的代码)
数据段 (字符串常量,已/未 初始化的全局变量,静态变量)
堆 (分配空间从大到小)
栈 (分配空间从小到大)
内核区 (最高)

  1. Tagged Pointer
    64bit后,引入了此技术
    未使用 NSNumber对象需要动态分配内存,维护引用计数
    使用后 指针内部变为 tag+data,数据存于指针中,指针不够存储,转为动态分配内存

  2. OC对象的内存管理

  • 新创建对象retainCount=1,计数器=0销毁,retain,new,copy等+1,release-1
  • ARC下通过 编译器特性llvm和runtime进行内存管理(自动生成setget,自动进行runtime清除引用)
  • 方法里有局部对象,出了方法立即释放吗 (会,arc下会,编译器特性或者runtime调用release)
  1. 深浅copy,拷贝的目的是为了产生一个副本对象,根原对象不影响
    其他对象自定义需实现 NSCpoying协议,实现 copyWithZone

  2. 引用计数器存储(https://blog.csdn.net/u013378438/article/details/82790332)
    64bit后,引用计数器放在了优化过的isa中,超过了 19位后,放sidetable
    sideTable内部有 (slock自旋锁 ,refcnts引用计数表 weak_table弱引用表)

  3. weak原理
    纵观weak引用的底层实现,其实原理很简单。就是将所有弱引用obj的指针地址都保存在obj对应的weak_entry_t中。当obj要析构时,会遍历weak_entry_t中保存的弱引用指针地址,并将弱引用指针指向nil,同时,将weak_entry_t移除出weak_table。

  4. dealloc
    释放函数依次为 (dealloc) (_objc_rootDealloc) (rootDealloc)(Objc_dispose)(objc_destructInstance)(free)
    在objc_destructInstance将指针变为nil

  5. 自动释放池

  • 自动释放池的主要底层数据结构是 _AutoreleasePool AutoreleasePoolPage,调用了 Autorelease的对象都是用 AutoreleasePoolPage。
  • 每个 AutoreleasePoolPage占4096个字节,除了内部成员变量,剩下空间用于放 Autorelease对象地址
  • 内部有 thread,parent,child双向链表
  • 调用push把 POOL_BOUNDARY 入栈,返回内存地址,pop时传入 POOL_BOUNDARY,
  • 主线程有2个Obsever,runloop Entry时 push
  • runloopBeforeWaiting时 pop,push
  • BeforeExit pop
    (https://www.jianshu.com/p/1b66c4d47cd7, )

magic:用来校验 AutoreleasePoolPage 的结构是否完整;
next:指向栈顶,也就是最新入栈的autorelease对象的下一个位置;
thread:指向当前线程;
parent:指向父节点
child:指向子节点
depth:表示链表的深度,也就是链表节点的个数
hiwat:表示high water mark(最高水位标记)

转载请注明出处。

你可能感兴趣的:(面试复习-内存管理)