欢迎大家来我们的iOS交流社区,一起来交流学习,我会定期分享一些我学习ios开发 主要逆向安防、架构设计、多线程,网络进阶,还有底层 的学习的资料
加微信邀请你加入 15388944845
1、内存布局
- stack:方法调用
- heap:通过alloc等分配内存
- bss:未初始化的全局变量等
- data:已初始化的全局变量等
- text:程序代码
2、内存管理方案
- TaggedPointer
- NONPOINTER_ISA
- 散列表
散列表
3、数据结构
- Spinlock_t "忙等"锁,轻量访问
- RefcountMap
size_t
- weak_table_t
4、MRC / ARC
- MRC alloc/retain/release/retainCount/autorelease/dealloc
- ARC LLVM和Runtime协作; ARC中禁止手动调用retain/release/retainCount/dealloc; 新增strong/weak属性关键字
5、引用计数
- alloc,最终调用calloc,此时引用计数为0
- retain实现
SideTable& table = SideTables()[this];
size_t& refcntStorage = table.refcnts[this];
refcntStorage += SIDE_TABLE_RC_ONE;
- release实现
SideTable& table = SideTables()[this];
RefcountMap::iterator it = table.refcnts.find(this);
it->second -= SIDE_TABLE_RC_ONE;
- retainCount实现
SideTable& table = SideTables()[this];
size_t refcnt_result = 1;
RefcountMap::iterator it = table.refcnts.find(this);
refcnt_result += it->second >> SIDE_TABLE_RC_SHIFT;
- dealloc
object_dispose()
objc_destructInstance()
clearDeallocating()
6. 弱引用
{
id __weak obj1 = obj;
}
{
id obj1;
objc_initWeak(&obj1, obj);
}
7、自动释放池
void *ctx = objc_autoreleasePoolPush();
...
objc_autoreleasePoolPop(ctx);
void *objc_autoreleasePoolPush(void) <=> void *AutoreleasePoolPage::push(void)
void objc_autoreleasePoolPop(void* ctx) <=> AutoreleasePoolPage::pop(void* ctx)
- 以栈为结点通过双向链表的形式组合而成
- 和线程一一对应
- RunLoop将要结束时调用AutoreleasePoolPage::pop()
- 多层嵌套就是多次插入哨兵对象
- for循环中含有内存消耗较大的场景时,如图片对象的创建,手动插入AutoreleasePool
8、循环引用
分类
- 自循环引用
- 相互循环引用
- 多循环引用
存在的场景
- 代理
- Block
- NSTimer
- 大环引用
解决方案
- __weak
- __block: MRC下,__block修饰的对象不回增加引用计数,避免循环引用; ARC下,__block修饰的对象会被强引用,无法避免循环引用,需要手动解环
- __unsafe_unretained:修饰对象不会增加引用计数,避免循环引用;但是被修饰对象被释放时,会产生悬垂指针
网友评论