NSMutableArray в цикле теряет память, даже когда я явно освобождаю его - PullRequest
2 голосов
/ 17 ноября 2011

В этом цикле происходит утечка памяти:

int64_t i,verylongnumber;

//misc. code

for(i=0;i<verylongnumber;i++){
    NSMutableArray *myArray = [[NSMutableArray alloc] initWithObjects:
            [NSNumber numberWithLongLong:65535],
            [NSNumber numberWithLongLong:65535],
            [NSNumber numberWithLongLong:65535],
            [NSNumber numberWithLongLong:65535],
            nil];
    [myArray removeAllObjects];
    [myArray release];
}

Я пробовал все, чтобы не допустить утечки памяти, но не могу. Я думаю, что это как-то связано с номерами NSN. Я предполагаю, что они созданы автоматически выпущенными, но означает ли это, что я должен освободить их индивидуально (то есть использовать alloc)? Как бы я вообще это сделал? Создать отдельную переменную для каждого NSNumber и вставить его в массив? Это похоже на большую работу. Я попытался [myArray removeAllObjects], но это не имело никакого значения. это в моей собственной теме с собственным пулом авто-релиза. Я не уверен, если это имеет значение.

Это исправлено:

Я добавил дополнительный пул авто-релиза внутри цикла:

int64_t i,verylongnumber;

//misc. code

for(i=0;i<verylongnumber;i++){

    NSAutoreleasePool *pool2 = [[NSAutoreleasePool alloc] init];

    NSMutableArray *myArray = [[NSMutableArray alloc] initWithObjects:
            [NSNumber numberWithLongLong:65535],
            [NSNumber numberWithLongLong:65535],
            [NSNumber numberWithLongLong:65535],
            [NSNumber numberWithLongLong:65535],
            nil];
    [myArray release];

    [pool2 drain];
}

Ответы [ 3 ]

6 голосов
/ 17 ноября 2011

Я возьму удар в этом ..

Вы можете удалить [myArray removeAllObjects], так как он является избыточным. NSArray сохраняют свои объекты, но они также освобождают их, когда сам массив освобождается.

Сами NSNumbers автоматически освобождаются. Однако, если вы делаете очень очень большой цикл, то эта автоматически освобожденная память фактически не будет освобождена до тех пор, пока не завершится цикл for и, в конечном счете, также и цикл выполнения (если вы не настроили где-то отдельный NSAutoreleasePool).

Итак, я могу видеть, как будет увеличиваться использование памяти, поскольку этот цикл повторяется, но по завершении он должен освободить память. Как вы пришли к выводу, что у вас есть утечка?

3 голосов
/ 17 ноября 2011

Вы ждете, чтобы увидеть, будут ли объекты выпущены в ближайшем будущем ?

Автоматически освобожденные объекты будут выпущены в какой-то момент в ближайшем будущем.В приведенном выше случае вы очень много раз создаете циклы, создавая много объектов.Они не будут выпущены в рамках этого кода.

В приложении с графическим интерфейсом это означает, что функция возвращается после запуска цикла выполнения.В консольном приложении это когда пул освобождается.

Проверить:

http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmAutoreleasePools.html

Пулы с автоматическим выпуском предоставляют механизм, с помощью которого вы можете отправить объектсообщение об отложенном выпуске.

Ключ - это точка отсрочки.

РЕДАКТИРОВАТЬ: (после комментария)

Обратите внимание, что вы можете опустошить пул.Другой вариант заключается в создании неавторизованных номеров (alloc / init) и явном освобождении в вашем длинном цикле.в зависимости от кода, это может быть желательно, так как удаление пула может освободить объекты, отложенные для освобождения, которые, как предполагает код в этом цикле / области, все еще отложены.Если вы хотите контролировать это, то управляйте этим.

1 голос
/ 17 ноября 2011

NSArray сохраняет объекты, когда они добавляются в NSArray.Это означает, что NSArray становится владельцем этого объекта.когда объект удаляется из NSArray или NSArray уничтожается, объект освобождается (счетчик ссылок -1).Если у объекта нет другого владельца, то объект уничтожается.
Следующий код создаст утечку памяти

NSNumber *number = [[NSNumber alloc]initWithFloat:floatValue]; //reference count is 1, you are the owner
[aArray addObject:number] //reference count is 2, aArray is also owner.  

Таким образом, чтобы устранить утечку памяти, вы должны освободить номер.

 NSNumber *number = [[NSNumber alloc]initWithFloat:floatValue]; //reference count is 1, you are the owner
[aArray addObject:number] //reference count is 2, aArray is also owner. 
[number release]; // reference count is 1, you are not owner og number    

Если вы добавляете объект автоматического выпуска в NSArray, нет необходимости освобождать этот объект.когда пул автообновления выталкивается, этот объект теряет свою собственность.
В вашем примере с каждым циклом for создается NSNumber, в то время как старый все еще находится в памяти в ожидании освобождения пула автозапуска.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...