如何创建/结束运行循环以正确释放内存?

时间:2015-10-21 20:28:50

标签: objective-c memory-management memory-leaks automatic-ref-counting sskeychain

在我的ARC iOS应用程序中,我正在运行for循环,最终导致大量内存分配开销。我想以某种方式结束我的for循环,分配最小/没有额外的内存。在这个例子中,我正在使用SSKeychain库,它允许我从钥匙串中获取东西。我通常只使用自动释放池并正确删除我的内存,但在这里我不知道是什么问题,因为我最终在循环结束时分配了70 MB的内存。我被告知我应该开始/结束一个运行循环来正确处理这个问题。想法?

for (int i = 0; i < 10000; ++i) {
            @autoreleasepool {
                NSError *  error2 = nil;
                SSKeychainQuery*  query2 = [[SSKeychainQuery alloc] init];
                query2.service = @"Eko";
                query2.account = @"loginPINForAccountID-2";
                query2.password = nil;
                [query2 fetch:&error2];
            } 
}

1 个答案:

答案 0 :(得分:1)

您用什么来衡量内存使用情况?

非常简单测试的结果......

在模拟器中运行,仅测量前后的驻留内存。

没有autoreleasepool ... 以27254784开头,以30212096结尾,使用2957312

使用autoreleasepool ... 以27316224开头,以27443200结尾,使用126976

显然,自动释放池可以防止内存变得太糟糕,而且在任何情况下我都看不到任何接近70MB的内存。

你应该运行乐器并获得有关行为的良好读数。

这是我入侵并运行的代码......

memchecker

static NSUInteger available_memory(void) {
    NSUInteger result = 0;
    struct task_basic_info info;
    mach_msg_type_number_t size = sizeof(info);
    if (task_info(mach_task_self(), TASK_BASIC_INFO, (task_info_t)&info, &size) == KERN_SUCCESS) {
        result = info.resident_size;
    }
    return result;
}

代码......

#define USE_AUTORELEASE_POOL 1

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    dispatch_async(dispatch_get_main_queue(), ^{
        NSUInteger beginMemory = available_memory();
        for (int i = 0; i < 10000; ++i) {
#ifdef USE_AUTORELEASE_POOL
            @autoreleasepool
#endif
            {
                NSError *  error2 = nil;
                SSKeychainQuery*  query2 = [[SSKeychainQuery alloc] init];
                query2.service = @"Eko";
                query2.account = @"loginPINForAccountID-2";
                query2.password = nil;
                [query2 fetch:&error2];
            }
        }
        NSUInteger endMemory = available_memory();

        NSLog(@"Started with %u, ended with %u, used %u", beginMemory, endMemory, endMemory-beginMemory);
    });

    return YES;
}