Как создать / завершить цикл выполнения, чтобы правильно освободить память?

В моем приложении ARC iOS я запускаю цикл for, который заканчивается большими накладными расходами памяти. Я хочу как-то завершить цикл for с минимальным выделением дополнительной памяти. В этом случае я использую библиотеку SSKeychain, которая позволяет мне получать вещи из цепочки для ключей. Я обычно просто использую пулы автоматического освобождения и правильно удаляю свою память, но здесь я не знаю, что не так, потому что в конце я получаю 70 МБ + памяти, выделенной в конце цикла. Мне сказали, что я должен запустить / завершить цикл выполнения, чтобы правильно справиться с этим. Мысли?

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 ответ

Что вы используете для измерения использования памяти?

Результаты очень простого теста...

Работая в симуляторе, измеряйте только резидентную память до и после.

Без автозапуска... Начинается с 27254784, заканчивается с 30212096, используется 2957312

С autoreleasepool... Начинается с 27316224, заканчивается с 27443200, используется 126976

Очевидно, что авто-релиз не позволяет памяти работать слишком плохо, и я не вижу, чтобы в каких-либо обстоятельствах использовалось что-то близкое к 70 МБ.

Вы должны запустить инструменты и получить хорошие показания о поведении.

Вот код, который я взломал и запустил...

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;
}
Другие вопросы по тегам