Как я могу избавиться от резидентной грязной памяти в Objective-C? - PullRequest
23 голосов
/ 25 марта 2011

Я смотрел видео Apple WWDC 2010 о расширенном анализе памяти с помощью инструментов, и из этого я смог найти много постоянной грязной памяти. Я понимаю, что наличие такого большого количества грязной памяти - плохая вещь (и, вероятно, объяснение того, что мое приложение так сильно зависало ...), но я не уверен, как это исправить. Куда мне смотреть?

Инструменты показывают мне много потенциально полезной информации, которая выглядит для меня как бред, например:

% of Res  Type                      Resident Size
18%       VM_ALLOCATE (8192 pages)  32.00 MB

Это в категории «Грязный» - 32 МБ постоянной грязной памяти - это много на устройстве, которое имеет только 256 МБ, верно? :) Есть еще несколько больших кусков, как это. Как мне отследить это до моего кода от Instruments? Или я должен просто забыть инструменты и искать конкретные проблемы в моем коде?

Ответы [ 4 ]

29 голосов
/ 03 апреля 2011

Видите ли вы этот 32 МБ фрагмент VM_ALLOCATE при запуске на устройстве или в симуляторе?

Я спрашиваю, потому что, когда я играл с инструментом выделения в приложении OS X, над которым я работаю, я также заметил 32-мегабайтный фрагмент VM_ALLOCATE, и мне интересно, является ли это побочным продуктом работы в Среда OS X Запуск на устройстве может дать вам другой набор данных.

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

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

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

Существуют также API-интерфейсы, которые можно использовать при загрузке объектов NSData, которые используют метод отображения памяти вместо чтения байтов методом перебора. Это может быть лучше, потому что это позволяет ОС лениво читать страницы с диска. С NSData (так как он не изменяем), он также может быть достаточно умным, чтобы пометить страницы только для чтения. Теоретически, это ценный намёк на то, что ОС может очищать эти страницы под давлением, поскольку знает, что они не могут измениться. Прочитайте документы для +[NSData dataWithContentsOfMappedFile:].

В отношении изображений я вспоминаю, что читал что-то, что предлагало избегать imageNamed:, за исключением изображений, которые вы регулярно используете в своем приложении (т.е. элементы пользовательского интерфейса). Особенно для больших изображений они могут оставаться в кеше, который вы не можете контролировать. (imageNamed: имела утечку в течение 2.x дней, но она была исправлена ​​в 3.x и совершенно безопасна для использования сегодня.) Используйте imageWithContentsOfFile: для больших изображений и изображений, которые не являются повторяющейся частью вашего пользовательского интерфейса .

Если вы загружаете изображения из сети, кэшируйте их на диске и освобождайте необработанные байты после создания UIImage. Если представления изображений выгружаются из-за нехватки памяти, вам не нужно подключаться к сети для повторной загрузки данных, но вы также не хотите сохранять две копии (NSData и UIImage) загруженными.

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

С новым xCode 4 все еще есть инструменты из xCode 3 с улучшенным пользовательским интерфейсом для профилирования вашего приложения, включая утечки и использование памяти.Я бы порекомендовал вам взглянуть на эти инструменты и запустить один за другим, чтобы увидеть, что они вам предоставляют.Вы можете получить доступ к этим инструментам в xCode 4 в главном меню Product, а затем -> Profile

Надеюсь, это поможет

1 голос
/ 01 апреля 2011

В инструментах нажмите включить снимки автоматически Измените режим просмотра на карту регионов. Найдите в путях имена файлов, которые вы используете, пока ваше приложение находится в vmpages И после того, как ты это очистишь. В примере с wwdc для видео они использовали шифрование для файла, и это подтолкнуло его к vmpages, без слишком сложного кода, чтобы предложить нечто большее, чем [библиотека сброса]: -)

0 голосов
/ 06 мая 2012

"Это в категории" Грязные "- 32 МБ постоянной грязной памяти ..." "Я также заметил 32-МБ кусок VM_ALLOCATE, и мне интересно ..."

Я вижутот же «VM_ALLOCATE (8192 страниц) 32 МБ» для резидентных, грязных и виртуальных столбцов в VM Tracker, когда я профилирую свои приложения в симуляторе.

Для сравнения, я профилировал (меньшую) демонстрациюприложения, созданные на основе очень информативного курса iTunes U Stanford - например, «Психолог» и «Графический калькулятор» - и в каждом из них есть одна и та же запись.

Я - «доменный парень»и пока еще не разбираюсь в деталях управления памятью, поэтому я не могу дать авторитетное объяснение, но кажется разумным сделать вывод, что это распределение связано с элементами Framework, общими для всех приложений, запущенных на Simulator,(Я не запускал их на устройстве.)

(К вашему сведению: Xcode 4.3 на MacBook Pro под управлением 10.7.3)

...