dispatch_async,执行后不释放内存

时间:2014-11-22 14:15:15

标签: ios memory dispatch-async

我有一个使用dispatch_async:

的函数
- (IBAction)action:(id)sender {
    int i=10000;
    NSString * data;
    dispatch_queue_t queue = dispatch_queue_create("com.wang.queue", NULL);
    __weak ViewController*  weakSelf = self;
    while(i>0)
    {
        @autoreleasepool {
            data = [[NSString alloc]initWithFormat:@"%i",i];
            NSString * str = data;
            dispatch_async(queue, ^{{
                [weakSelf print:str];
            }});
            i--;
        }
    }
}


-(void) print:(NSString*)str
{
    NSLog(@"%@",str);
    str = nil;
}

然后我连续按下按钮五次。在整齐地运行之后,记忆力并没有减少。所以我使用Instrument来分析占用内存的位置。 像这样:

img.bbs.csdn.net/upload/201411/19/1416403576_473540.png

它显示了"数据"被释放了。它是" VM:性能工具数据"谁占据了记忆。细节是:

img.bbs.csdn.net/upload/201411/19/1416403630_487530.png

我认为" dispatch_async"从来没有被释放过。

谁能告诉我是什么让内存像这样表现?感谢!

1 个答案:

答案 0 :(得分:1)

有几点想法:

  1. 您正在使用NSString个对象,但NSString的各种缓存/优化可能会扭曲此类分析。您通常应该警惕使用NSString对象进行内存分析。您可能希望使用NSObject或某些自定义类重复此操作。我不认为这是问题所在,但在调试内存分配时总是要注意这一点。

  2. 您正在使用@autoreleasepool,但您没有自动释放对象。我假设你把那个池放在一起是为了小心,但是你的主data / str对象没有自动释放,所以这个池可能不会给你买任何东西。此外,无论如何,FYI,GCD都使用自己的自动释放池。

  3. 即使您确实拥有autorelease个对象,data变量也会定义在@autoreleasepool范围之外,并且您永远不会消除该data内部的最终强引用游泳池,所以游泳池不会有任何成就。您应该为变量使用尽可能窄的范围。在这种情况下,我只是退出str变量,只使用您的本地{{1}}变量。

  4. 有人建议你可能有一个保留周期(也就是说,一个强大的参考周期)。没有这样的循环,至少在与我们共享的代码中没有。

  5. 说完所有这些之后,对我来说,“性能工具数据”似乎与您正在创建的10,000个对象无关。你有347个对象,占180 mb。

    我想知道这个“性能数据”是否是Instruments本身正在创建的东西(例如快照,堆栈跟踪等)。我做了一些实验,但无法重现你描述的行为。我已经尝试更改Xcode方案以打开一堆日志选项(例如僵尸,内存检查,日志记录等),我尝试更改仪器以记录最大量的信息(例如频繁的快照等,保持丢弃项目,记录参考计数等)。所有这一切都无济于事。

    也许您可以分享您可能已打开的乐器设置(或尝试关闭一些)。同样适用于您的应用程序的方案(确保您已关闭不必要的日志记录)。另外,请编辑您的问题,向我们提供有关您正在使用的Xcode / Instruments版本以及目标操作系统版本等的详细信息。