Как создать / завершить цикл выполнения, чтобы правильно освободить память?
В моем приложении 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;
}