Файлы с отображением в памяти и сценарии с нехваткой памяти - PullRequest
38 голосов
/ 30 мая 2011

Как платформа iOS обрабатывает отображенные в памяти файлы в сценариях с нехваткой памяти? Под сценариями нехватки памяти я подразумеваю, когда ОС отправляет уведомление UIApplicationDidReceiveMemoryWarningNotification всем наблюдателям в приложении.

Наши файлы отображаются в память с помощью +[NSData dataWithContentsOfMappedFile:], документация для которой гласит:

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

Означает ли это, что ОС также удаляет карты, когда они больше не используются? Можно ли пометить страницы как неиспользуемые? Эти данные доступны только для чтения, если это меняет сценарий. Как насчет того, чтобы использовать mmap() напрямую? Было бы это предпочтительнее?

Ответы [ 6 ]

19 голосов
/ 02 июня 2011

Файлы с отображением в памяти копируют данные с диска в память за страницу. Неиспользуемые страницы могут быть выгружены так же, как и любая другая виртуальная память, если только они не были подключены к физической памяти с использованием mlock(2). Отображение памяти оставляет определение того, что копировать с диска в память и когда в ОС.

Переход с уровня Foundation на уровень BSD для использования mmap вряд ли будет иметь большое значение, кроме того, что код, который должен взаимодействовать с другим кодом Foundation, несколько более неудобен.

10 голосов
/ 08 июня 2011

(Это не ответ, но будет полезной информацией.)

От @ ID_AA_Carmack твит ,

@ ID_AA_Carmack сопоставлены с памятью iOSфайлы автоматически отображаются в условиях нехватки памяти?(используя + [NSData dataWithContentsOfMappedFile]?)

ID_AA_Carmack ответил за это,

@ KhrobEdmonds да, это одно из больших преимуществ использования сопоставленных файлов в iOS.Хотя я использую mmap ().

Я не уверен, что это правда или нет ...

7 голосов
/ 07 июня 2011

Из моих экспериментов NSData не отвечает на предупреждения памяти.Я протестировал, создав NSData с отображением в памяти и получив доступ к частям файла, чтобы он был загружен в память и, наконец, отправил предупреждения памяти.После предупреждения об использовании памяти не произошло уменьшения использования памяти.Ничто в документации не говорит о том, что память заставит NSData снизить реальное использование памяти в ситуациях нехватки памяти, поэтому я полагаю, что она не реагирует на предупреждения памяти.Например, документация NSCache говорит, что он будет пытаться играть хорошо в отношении использования памяти, плюс мне сказали, что он отвечает на предупреждения о нехватке памяти, которые выдает система.

Также в моих простых тестах на iPod Touch (4-го поколения) мне удалось сопоставить около 600 мегабайт файловых данных с использованием виртуальной памяти +[NSData dataWithContentsOfMappedFile:].Затем я начал получать доступ к страницам через свойство bytes в экземпляре NSData.Когда я это сделал, реальная память начала расти, но перестала расти на 30 мегабайт реального использования памяти.Таким образом, способ его реализации ограничивает объем используемой памяти.

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

4 голосов
/ 08 июня 2011

Если iOS похожа на любой другой Unix - и я бы поставил на это деньги - страницы в области mmap () не «выгружаются»;они просто удаляются (если они чистые) или записываются в базовый файл, а затем удаляются (если они грязные).Этот процесс называется «выселением» страницы.

Поскольку ваша карта памяти доступна только для чтения, страницы всегда будут чистыми.

Ядро решит, какие страницы выселить, когда физическая память получиттугие.

Вы можете дать ядру подсказки о том, какие страницы вы бы предпочли, чтобы они сохранялись / выселялись, используя posix_madvise () .В частности, POSIX_MADV_DONTNEED говорит ядру, что вы можете свободно выселять страницы;или, как вы говорите, «пометить страницы как неиспользуемые».

Было бы довольно просто написать несколько тестовых программ, чтобы увидеть, соблюдает ли iOS подсказку «не нужен».Я уверен, что он получен из BSD.

1 голос
/ 02 июня 2011

Стандартные методы виртуальной памяти для файловой памяти говорят, что ОС может свободно выбрасывать страницы, когда захочет, потому что она всегда может получить их снова позже.Я не использовал iOS, но такое поведение виртуальной памяти было во многих других операционных системах в течение длительного времени.

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

0 голосов
/ 03 апреля 2012

Метод dataWithContentsOfMappedFile: больше не поддерживается в iOS5.

Используйте mmap, чтобы избежать подобных ситуаций.

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