Как сохранить низкое потребление памяти при большом количестве строк NSS или как освободить строки NSStrings? - PullRequest
0 голосов
/ 04 марта 2011

Я работаю над приложением, которое импортирует (очень) большой CSV-файл в базовые данные для отлова. Процесс идет примерно так:

  1. Разбор файла построчно в NSMutableArray, полный NSStrings
  2. После X числа строк импортируйте массив в Core Data (это включает манипулирование и, в некоторых случаях, создание новых строк NSStrings)
  3. [NSMutableArray removeAllObjects];
  4. Прополоскать и повторить

На первый взгляд кажется, что память должна быть освобождена в конце каждого цикла. Однако с большими файлами я обнаружил, что приложение вылетает после нескольких предупреждений о нехватке памяти. Запуск инструмента утечки говорит мне, что большая часть памяти используется объектами CFString, что, как я понимаю, связано с объектами NSString (хотя я не знаю, как)

Я понимаю, что строки NSString используются всякий раз, когда это возможно, и что они не действуют точно так же, как и другие объекты, связанные с памятью, хотя я не понимаю ни одной из деталей. Как я могу восстановить память, которую используют мои объекты NSString?

Ответы [ 3 ]

2 голосов
/ 04 марта 2011

Я предполагаю, что у вас нет утечки памяти.

Если вы используете слишком много автоматически выпущенного объекта, это может произойти

Вы пытаетесь подписаться

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

  2. Не используйте объект autorelease в цикле синтаксического анализа - выполняйте ручное выделение и освобождение объекта после завершения работы.

2 голосов
/ 04 марта 2011

Запуск инструмента утечки говорит мне, что большая часть памяти используется объектами CFString, что, как я понимаю, связано с объектами NSString (хотя я не знаю, как)

NSString на самом деле является кластером классов.Хотя вы думаете, что работаете с NSStrings, вы почти наверняка работаете с одним из его подклассов.Каркас Какао выбирает, какой подкласс использовать в зависимости от обстоятельств.

CFString на самом деле вообще не NSString, это чистый строковый объект C, используемый Core Foundation .Тем не менее, вы обнаружите, что это "бесплатный звонок для NSString.Это означает, что для Какао это выглядит как строка NSString.Причина, по которой вы часто используете CFString, заключается в том, что любой API-интерфейс Cocoa, который вы используете для получения этих строк, в конечном итоге выполняет свою работу в Core Foundation.

В любом случае, все, что не имеет отношения к вашей проблеме, за исключением того факта, что множество строк CFString более или менее означает то же самое, что множество строк NSStrings.Чтобы уменьшить объем памяти, вам нужны вложенные пулы автоматического выпуска, как уже сказал Гириш.В качестве первого шага измените ваш алгоритм следующим образом:

  1. Создайте новый пул автоматического выпуска.
  2. Строковый анализ файла в NSMutableArray полностьюNSStrings
  3. После X числа строк импортируйте массив в Core Data (это включает манипулирование и, в некоторых случаях, создание новых NSStrings)
  4. [NSMutableArray removeAllObjects];
  5. истощить пул авто-релиза
  6. Промыть и повторить (начать с 0)

Если это не помогает или только помогает, рассмотрите возможность брекетинга только при разборес авто-релизным бассейном.

0 голосов
/ 04 марта 2011

Вы не можете быть уверены, что память используется только NSStrings.Я предлагаю вам проверить это тщательно.Попробуйте перейти к «Построить и проанализировать», это поможет вам обнаружить утечки.

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

[NSString stringWithFormat@""];

, создайте свой собственный объект и отпустите его, как только закончите.

NSString * string = [[NSString alloc]initWithFormat:@""];
//use string object
[string release];

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

или создаете пул автоматического выпуска

NSAutoReleasePool * pool = [[NSAutoReleasePool alloc]init];
// do you coding, creation of objects, releasing them, whatever...
[pool drain]; or [pool release];

Также посмотрите эти советы по управлению памятью

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