使用NSURLConnection和dispatch_async时的内存永远不会被释放

时间:2013-08-21 22:33:00

标签: ios memory nsurlconnection grand-central-dispatch dispatch-async

为了知道东西是如何工作的,我写了一个简单的iPhone应用程序,它有一个开始按钮。按下该按钮会触发执行以下操作的操作:

- (IBAction)start:(id)sender {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    @autoreleasepool {
        NSString *urlString = @"http://www.aftonbladet.se";
        NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:urlString]];
        NSHTTPURLResponse *response = nil;
        NSError *error = nil;
        NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
        if (error) {
            NSLog(@"Error: %@", [error localizedDescription]);
        }
        if (data) {
            NSLog(@"Data length: %d", [data length]);
        }
        if (response) {
            NSLog(@"Status code: %d", [(NSHTTPURLResponse*)response statusCode]);
        }
        [ViewController ReportMemory];
      }
});

}

ReportMemory函数如下所示:

+ (void)ReportMemory {
struct task_basic_info info;
mach_msg_type_number_t size = sizeof(info);
kern_return_t kerr = task_info(mach_task_self(),
                               TASK_BASIC_INFO,
                               (task_info_t)&info,
                               &size);
if( kerr == KERN_SUCCESS ) {
    NSLog(@"Memory in use: %u kB", info.resident_size/1024);
} else {
    NSLog(@"Error with task_info(): %s", mach_error_string(kerr));
}

}

我已经读过全局队列有自动释放池,但是它们只是间歇性地清空,所以我在使用和不使用@autoreleasepool宏的情况下尝试过,我看不出内存使用方面的任何差异。

问题是,为什么每次按下开始按钮时ReportMemory会显示越来越多的内存?我原以为在某些时候自动释放池会被清空。但在我的情况下,它会不断累加,直到我收到一些内存警告,并且当ReportMemory报告使用了大约400MB时,应用程序将关闭。

请注意,像这样使用sendSynchronousRequest仅用于演示目的。

1 个答案:

答案 0 :(得分:1)

我运行了你在Allocations Instrument中发布的代码,我从这个方法的一个边缘调用中看到的唯一明显的堆增长来自HTTP cookie存储。敲打它一分钟左右,堆分配看起来像这样:

Instruments Heap Trace

简而言之,是的,它会增长,但每隔一段时间它就会释放出一堆累积的资源。我怀疑这个代码没有捕获到其他东西。你应该在仪器中运行你的(整个)应用程序,看看发生了什么。