
1. 自动释放池
查看CPP代码
自动释放池 ,
进入大括号的时候,创建一个obj;
然后括号里面创建的对象都会被自动添加autorelease(ARC),被push到池中;
在出了大括号后,把自动释放池内添加的对象进行释放
自动释放池主要的底层数据结构是
__AtutoreleasePool , AutoreleasePoolPage
2. AutoreleasePoolPage的结构 next : 执行下一个存储位(下一个能放autorelease对象地址的区域)
调用push方法会将一个POOL_BOUNDARY入栈,并返回其存放的内存地址next = begin 说明page是空的
next = end 说明page是 满的(fullpage)
hotPage
coldPage当前正在使用的page
不被使用的page,一般是因为已经被装满了.
一个page会有一定的空间(4096-56)来装入对象,当page的空间还没有 满,还可以被装入对象时,这个page就是hotPage;表明再有对象要被装入,就会装到这个Page中,
如果这个page被装满了,next会=end,同时创建一个新的poolPage2,page的child指向这个新的poolPage2. page会变成coldpage,新的poolPage2成为hotPage.
以后再有什么 *** 作,都会从这个hotpage开始.比如pop,addObj,push
3. 源码 1. push() 这里的push 只是大括号开始时push,会向里面入栈一个POOL_BOUNDARYadd(obj)也相当于入栈POOL_BOUNDARY
obj 指向的地址也就是POOL_BOUNDARY的地址
POOL_BOUNDARY : 自动释放池的边界
2. autorelease 往pool中添加对象 , ARC下 自动释放池找那个创建的对象会被自动添加autorelease
3. pop()
从hotPage , --page->next 来获取对象,然后release
4. Runloop & autoreleasepool iOS在主线程的runloop中注册了两个observer 第一个observer :
监听了KCFRunLoopEntry时间,会调用objc_autoreleasePoolPush()第二个observer :
监听了KCFRunLoopBeforeWaiting事件,会调用objc_autoreleasePoolPop(),objc_autoreleasePoolPush()监听了KCFRunLoopBeforeExit事件,会调用objc_autoreleasePoolPop()
这样push 和 pop 就会形成一个闭环,确保成对出现.
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)