内存管理

一、内存布局
内核区-》栈(stack)-》堆(heap)-》未初始化数据(.bss)-》已初始化数据(.data)-》代码段(.text)-》保留

在ios中定义的方法或者函数都是在内存的栈区进行工作的,栈是由高地址向低地址。
创建的对象或者block进行copy之后会转移到堆上去,堆的内存地址是由低地址向高地址增长

stack:方法调用
heap:通过alloc分配的对象,copy之后的block
bss:未初始化的全区变量
data:已初始化的全局变量
text:程序代码

iOS是怎么样进行管理的:小对象是TaggedPointer,64位架构下NONPOINTER_ISA,散列表(弱引用表,和应用计数表)
arm64位下的NONPOINTER_ISA上的64位0或1分表存储和表示了很多信息
side tables(散列表)是一个哈希表里面里面存储了很多side table,每个side table里存储了spinlock_t(自旋锁)、RefcountMap(引用计数)、weak_table_t(弱引用表),为什么是多个side table,是因为为了解决访问效率问题,采用了分离所。
Spinlock_t 是忙等锁,适用于轻量级的访问
RefcountMap 使用哈希表来实现的,为了提高查找效率,插入和取出是通过同一个哈希算法来决定的,避免了遍历
weak_table_t 也是一张哈希表

二、应用计数

自动引用计数ARC是LLVM(编译器)和Runtime协作的结果,编译器在编译的时候在相应的地方插入了release和autorelease,arc中禁止调动retain、release retainCount、dealloc,arc中新增了weak和strong关键字

alloc:经过一系列的调用最终调用了c函数的calloc,此时并没有设置引用计数为1
retain :通过两次的hash查找对其引用计数进行+1
release:通过hash到sedetable中查找到相应的值进行-1操作
retianCount:定义了一个局部变量1,再加上去sidetable中查出的应用计数值,所以alloc出来后的引用计数并没有设置为1
dealloc:首先要判断是否可以直接释放(nonpointer_isa,weakly_refrenced,has_assoc,has_cxx_dtor,has_table_rc)如果可以则直接调用free,如果不行则需要调用object_dispose,通过dealloc实现源码可以判断关系对象在使用后不需要手动销毁
一个对象由weak指针指向他,对象被销毁了为什么指针会置为nil,是因为对象的dealloc对若引用指针置为nil(weak_clear_no_lock)

三、自动释放
自动释放池是怎么实现的,是以栈为节点通过双向链表形式组合而成的,是和线程一一对应的,AutoreleasePoolPage就相当于每一个节点
@autoreleasepool相当于如下代码
AutoreleasePoolPage::push
{
代码片段
}
AutoreleasePoolPage::pop
在当次runloop将要结束的时候会调用AutoreleasePoolPage::pop
多层嵌套调用是多次插入哨兵报对象(next)
使用场景:在for循环中alloc图片数据等内存消耗比较大的场景中插入autoreleasePool,在每一次for循环都进行释放来防止内存占用过大

四、循环引用
自循环引用、相互循环引用(代理)、多循环引用
破解方法:避免产生循环引用,在合适的时机断开引用,__waek,__block(在mrc下不会增加引用计数,避免了循环引用,arc下修饰会被对象强引用,无法避免循环引用,需手动破解),__unsafe_unretained(修饰对象不会增加引用计数,可以避免循引用,如果被修饰对象在某一时机被释放,会产生悬垂指针不安全)

NSTimer的循环引用问题
NSTimer产生是会由当前线程的runloop强引用,如果是重复的NSTimer需要建立一个中间对象,定义一个中间对象,分别对timer和vc进行弱引用,在中间对象中进行定时器方法的调用,如果发现vc被销毁了对nstimer进行invalidate和置为nil

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,463评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,868评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,213评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,666评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,759评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,725评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,716评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,484评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,928评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,233评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,393评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,073评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,718评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,308评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,538评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,338评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,260评论 2 352

推荐阅读更多精彩内容

  • 1、内存布局 stack:方法调用 heap:通过alloc等分配对象 bss:未初始化的全局变量等。 data:...
    AKyS佐毅阅读 1,594评论 0 19
  • 内存布局 stack(栈区): 方法调用 heap(堆区):通过alloc等分配的对象 bss:未初始化的全局变量...
    Jimmy_L_Wang阅读 620评论 1 3
  • 一.面试问题 使用CADisplayLink、NSTimer有什么注意点?循环引用、NSTimer定时器不准 介绍...
    蔚尼阅读 856评论 0 1
  • 1. 对象与类 1.1 对象 对象(Class或id)内部只有一个isa_t联合体指针。isa_t联合体内部只有两...
    我才是臭吉吉阅读 718评论 0 2
  • 内存分配方式 Objective-C内存管理方式 1、TaggedPointer iPhone5s开始采用64bi...
    一只长毛猫阅读 480评论 0 2