objc_autoreleasePoolPrint() 源码分析

文章深入分析了Objective-C中自动释放池(AutoreleasePool)与项目中偶发崩溃的可能关联,通过阅读并解释objc4的开源源码,特别是objc_autoreleasePoolPrint()函数,展示了如何打印autoreleasepool中的对象信息。文中示例代码演示了对象创建、引用计数变化及打印过程,揭示了内存管理的细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

背景:

        最近公司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!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值