背景:
最近公司metal项目偶发莫名其妙的崩溃,怀疑跟autoreleasepool 有关系,objc_autoreleasePoolPrint() 这个方法打印auto release pool page管理对的对象,好在objc4已经开源了,下边就是对它的源码分析
源码
void
_objc_autoreleasePoolPrint(void)
{
AutoreleasePoolPage::printAll();
}
static void printAll()
{
_objc_inform("##############");//打印########号
_objc_inform("AUTORELEASE POOLS for thread %p", objc_thread_self());//打印线程ID
AutoreleasePoolPage *page;
ptrdiff_t objects = 0;
for (page = coldPage(); page; page = page->child) {//找到每页保存对象个数
objects += page->next - page->begin();
}
_objc_inform("%llu releases pending.", (unsigned long long)objects);//总共管理对象个数打印出来
if (haveEmptyPoolPlaceholder()) {//判断是否页表是空的,如果是空的则打印结束符号
_objc_inform("[%p] ................ PAGE (placeholder)",
EMPTY_POOL_PLACEHOLDER);
_objc_inform("[%p] ################ POOL (placeholder)",
EMPTY_POOL_PLACEHOLDER);
}
else {
for (page = coldPage(); page; page = page->child) {//遍历每个页表打印出来对应的数据
page->print();
}
}
_objc_inform("##############");//打印结尾符号
}
void print()
{
_objc_inform("[%p] ................ PAGE %s %s %s", this,
full() ? "(full)" : "",
this == hotPage() ? "(hot)" : "",
this == coldPage() ? "(cold)" : "");
check(false);
for (id *p = begin(); p < next; p++) {
if (*p == POOL_BOUNDARY) {
_objc_inform("[%p] ################ POOL %p", p, p);
} else {
_objc_inform("[%p] %#16lx %s",
p, (unsigned long)*p, object_getClassName(*p));
done:;
}
}
}
上边会分析所有页表,把每个页表的对象打印出
接下来我们下边的代码以及打印的数据
#import <Foundation/Foundation.h>
#import "Test.h"
extern void _objc_autoreleasePoolPrint(void);
id getOc()
{
return [[Test alloc] init];
}
int main(int argc, const char * argv[]) {
@autoreleasepool {
NSObject *pObjecdt11 = nil;
_objc_autoreleasePoolPrint();
NSObject *pObjecdt1 =getOc();
_objc_autoreleasePoolPrint();
@autoreleasepool
{
NSObject *pObjecdt =getOc();
NSObject *pObjecdtA =getOc();
NSLog(@"%@ %@", pObjecdt, pObjecdtA);
NSLog(@"refCount=%d", CFGetRetainCount((__bridge void *)pObjecdt));
_objc_autoreleasePoolPrint();
@autoreleasepool
{
NSObject *pObjecdt =getOc();
_objc_autoreleasePoolPrint();
}
pObjecdt11 = pObjecdt;
NSLog(@"refCount=%d", CFGetRetainCount((__bridge void *)pObjecdt));
_objc_autoreleasePoolPrint();
}
_objc_autoreleasePoolPrint();
NSLog(@"refCount=%d", CFGetRetainCount((__bridge void *)pObjecdt11));
}
return 0;
}
objc[36922]: ##############
objc[36922]: AUTORELEASE POOLS for thread 0x1000dedc0
objc[36922]: 0 releases pending.
objc[36922]: [0x1] ................ PAGE (placeholder)
objc[36922]: [0x1] ################ POOL (placeholder)
objc[36922]: ##############
objc[36922]: ##############
objc[36922]: AUTORELEASE POOLS for thread 0x1000dedc0
objc[36922]: 2 releases pending.
objc[36922]: [0x104009000] ................ PAGE (hot) (cold)
objc[36922]: [0x104009038] ################ POOL 0x104009038
objc[36922]: [0x104009040] 0x102a04100 Test
objc[36922]: ##############
2023-05-22 10:53:50.882848+0800 autoreleasepool[36922:1536266] <Test: 0x1005040c0> <Test: 0x1029addc0>
2023-05-22 10:53:52.129734+0800 autoreleasepool[36922:1536266] refCount=2
objc[36922]: ##############
objc[36922]: AUTORELEASE POOLS for thread 0x1000dedc0
objc[36922]: 5 releases pending.
objc[36922]: [0x104009000] ................ PAGE (hot) (cold)
objc[36922]: [0x104009038] ################ POOL 0x104009038
objc[36922]: [0x104009040] 0x102a04100 Test
objc[36922]: [0x104009048] ################ POOL 0x104009048
objc[36922]: [0x104009050] 0x1005040c0 Test
objc[36922]: [0x104009058] 0x1029addc0 Test
objc[36922]: ##############
objc[36922]: ##############
objc[36922]: AUTORELEASE POOLS for thread 0x1000dedc0
objc[36922]: 6 releases pending.
objc[36922]: [0x104009000] ................ PAGE (hot) (cold)
objc[36922]: [0x104009038] ################ POOL 0x104009038
objc[36922]: [0x104009040] 0x102a04100 Test
objc[36922]: [0x104009048] ################ POOL 0x104009048
objc[36922]: [0x104009050] 0x1005040c0 Test
objc[36922]: [0x104009058] 0x1029addc0 Test
objc[36922]: [0x104009060] ################ POOL 0x104009060
objc[36922]: ##############
2023-05-22 10:54:16.369384+0800 autoreleasepool[36922:1536266] Test Destory!
2023-05-22 10:54:19.030186+0800 autoreleasepool[36922:1536266] refCount=3
objc[36922]: ##############
objc[36922]: AUTORELEASE POOLS for thread 0x1000dedc0
objc[36922]: 5 releases pending.
objc[36922]: [0x104009000] ................ PAGE (hot) (cold)
objc[36922]: [0x104009038] ################ POOL 0x104009038
objc[36922]: [0x104009040] 0x102a04100 Test
objc[36922]: [0x104009048] ################ POOL 0x104009048
objc[36922]: [0x104009050] 0x1005040c0 Test
objc[36922]: [0x104009058] 0x1029addc0 Test
objc[36922]: ##############
2023-05-22 10:54:19.030435+0800 autoreleasepool[36922:1536266] Test Destory!
objc[36922]: ##############
objc[36922]: AUTORELEASE POOLS for thread 0x1000dedc0
objc[36922]: 2 releases pending.
objc[36922]: [0x104009000] ................ PAGE (hot) (cold)
objc[36922]: [0x104009038] ################ POOL 0x104009038
objc[36922]: [0x104009040] 0x102a04100 Test
objc[36922]: ##############
2023-05-22 10:54:20.730669+0800 autoreleasepool[36922:1536266] refCount=1
2023-05-22 10:54:20.730753+0800 autoreleasepool[36922:1536266] Test Destory!
2023-05-22 10:54:20.730804+0800 autoreleasepool[36922:1536266] Test Destory!