На самом деле все выглядит нормально.Рост, который вы видите, выглядит следующим образом:
_mutArr = [[NSMutableArray alloc] initWithCapacity:102430];
for(int i = 0; i < 1024*1024*30; i++){
[_mutArr addObject:@(i)];
}
Итак, вы добавляете свои числа в массив _mutArr
и добавляете их 1024*1024*30
.Когда этот цикл завершается, _mutArr
является действительным и полным, он сохраняет все эти числа.Это даже не изменится добавлением другого пула автоматического выпуска в этом цикле, потому что ваш массив не позволит освободить эти числа.
Теперь, после вызова этого конструктора, у вас есть
@autoreleasepool {
BigMemObj *mem = [[BigMemObj alloc] init];
}
, поэтомув этот момент пул автозапуска будет исчерпан, и все цифры внутри BigMemObj
экземпляра mem
будут освобождены, и ваша память вернется в нормальное состояние.
Вы можете ожидать, что ваше приложение будет продолжать расти в памяти без вызова @autoreleasepool
.Но нет никаких изменений, если вы удалите этот вызов.Причиной этого является то, что ни один из вашего кода вообще не использует пул автоматического выпуска.Ваш код переводит (не-ARC):
NSMutableArray *arr = [[NSMutableArray alloc] init];
for(int i = 0 ; i < 10000; i++){
@autoreleasepool {
BigMemObj *mem = [[BigMemObj alloc] init];
[mem release];
}
}
[arr release];
Но вам понадобится ваш autoreleasepool
, только если он был
NSMutableArray *arr = [[NSMutableArray alloc] init];
for(int i = 0 ; i < 10000; i++){
@autoreleasepool {
BigMemObj *mem = [[[BigMemObj alloc] init] autorelease];
}
}
[arr release];
*1024* Чтобы иметь ситуацию, когданеобходим пул автоматического выпуска:
NSMutableArray *allBigValues = [[NSMutableArray alloc] init];
NSString *path = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"profile.png"];
for(int i = 0; i<100000; i++){
@autoreleasepool {
[allBigValues addObject:[UIImage imageWithContentsOfFile:path]];
[allBigValues removeAllObjects];
}
}
Если в этом коде вы удалите пул автоматического выпуска, он будет расти в памяти до завершения цикла.Причина этого заключается в том, что imageWithContentsOfFile
использует пул автоматического выпуска, и все изображения, созданные этим методом, будут выпущены только после того, как пул будет очищен.Поскольку основной пул не будет освобожден внутри цикла, нам нужно создать еще один.
В итоге этот код работает хорошо, но как только вы удалите часть @autoreleasepool
, он начнет расти в памяти и, вероятно, вылетит.ваше приложение.
Примечание 1: Вам нужно добавить изображение profile.png
в ваше приложение, чтобы этот код работал (просто перетащите его среди исходных файлов, а не ресурсов).
Примечание 2: Мы используем «сток», когда речь идет о пулах, потому что это было именем метода, который вам нужно было вызывать, когда вы хотели, чтобы пул удалил свои объекты.Вот как это было:
for(int i = 0; i<100000; i++){
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
[allBigValues addObject:[UIImage imageWithContentsOfFile:path]];
[allBigValues removeAllObjects];
[pool drain];
}