记录一次内存泄漏排查历程

背景

  通过在deinit方法内打印日志,发现某个ViewController的deinit方法没有执行,决定排查下具体的原因。

方案1,instruments排查

  打开instruments,按照内存泄漏的流程进行检测,反复进入,退出目标ViewController,检查instruments法相并没有定位到内存泄漏的代码,为了保险起见,又参考了网上的检测流程反复多次进行检测,结果都是一样没有定位到内存泄漏的具体代码。

方案2:Xcode Analysis

  使用Xcode的Analysis 功能确实分析出来了一些内存泄漏的代码,但是和目标ViewController没有关系。

方案3, 代码注释法

通过对目标ViewController的代码不断进行注释,检查deinit方法是否会执行,不断缩小范围,最终定位到一行代码,如下:

 IZoneInterfaceiOS.sharedInstance()?.traceHandler = self

traceHandler的定义如下:

@property(weak, nonatomic) id<IZoneTraceCb> traceHandler;

根据目前的信息看,一个被声明为weak的属性,不可能还会出现被持有不释放造成内存泄漏的情况。
继续排查使用的地方,发现只有一个地方进行了使用,代码如下:

void sdk_log_cb(SdkLogLevel level, const char* msg)
{
    NSString* log_msg = [NSString stringWithUTF8String:msg];
        if ([IZoneInterfaceiOS sharedInstance].traceHandler)
        {
            [[IZoneInterfaceiOS sharedInstance].traceHandler onTrace:(ZoneLogLevel)level log:log_msg];
        }
 }

将使用到traceHandler的代码注释掉,发现内存泄漏不存在了,注释掉以后的代码如下:

void sdk_log_cb(SdkLogLevel level, const char* msg)
{
    NSString* log_msg = [NSString stringWithUTF8String:msg];
       // if ([IZoneInterfaceiOS sharedInstance].traceHandler)
        //{
          //  [[IZoneInterfaceiOS sharedInstance].traceHandler onTrace:(ZoneLogLevel)level log:log_msg];
       // }
 }

然后把只注释掉如下代码:

void sdk_log_cb(SdkLogLevel level, const char* msg)
{
    NSString* log_msg = [NSString stringWithUTF8String:msg];
        if ([IZoneInterfaceiOS sharedInstance].traceHandler)
        {
          //  [[IZoneInterfaceiOS sharedInstance].traceHandler onTrace:(ZoneLogLevel)level log:log_msg];
        }
 }

分析可知,只要是在这个函数里用了traceHandler,就会产生内存泄漏,及时是仅仅打印traceHandler也会泄漏。后来验证了一下,确实如此。
仔细思考了发现这个函数是C,C++的函数,在执行的时候会对traceHandler默认执行retain操作,但是这个traceHandler是OC对象,释放需要OC来执行release操作,,但是ARC下已经不能手动执行release操作了。决定把这段代码放到自动释放池中,当执行完后,自动执行一下release操作。验证后发现确实如此,也解决了内存泄漏。修改后的代码如下:

void sdk_log_cb(SdkLogLevel level, const char* msg)
{
    NSString* log_msg = [NSString stringWithUTF8String:msg];
    @autoreleasepool {
        if ([IZoneInterfaceiOS sharedInstance].traceHandler)
        {
            [[IZoneInterfaceiOS sharedInstance].traceHandler onTrace:(ZoneLogLevel)level log:log_msg];
        }
    }
    
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值