Подтвердить что ты не робот

Mmap и использование памяти

Я пишу программу, которая получает огромное количество данных (в разных размерах) из сети, обрабатывает их и записывает их в память. Поскольку некоторые части данных могут быть очень большими, мой текущий подход ограничивает используемый размер буфера. Если кусок больше максимального размера буфера, я записываю данные во временный файл и затем читаю файл в кусках для обработки и постоянного хранения.

Мне интересно, можно ли это улучшить. Я читал о mmap некоторое время, но я не уверен на сто процентов, если это может мне помочь. Моя идея - использовать mmap для чтения временного файла. Помогает ли это в любом случае? Главное, о чем я беспокоюсь, это то, что иногда большая часть данных не должна заполнять мою основную память, из-за чего все остальное должно быть заменено.

Также, как вы считаете, подход с временными файлами полезен? Должен ли я это делать или, может быть, должен ли я доверять менеджеру Linux-памяти для выполнения этой работы? Или я должен вообще что-то сделать?

4b9b3361

Ответ 1

Mmap может помочь вам в некотором роде, я объясню несколько гипотетических примеров:

Первое: предположим, что у вас закончилась нехватка памяти, а ваше приложение, имеющее 100MB кусок памяти malloc'а, получает 50% от него, это означает, что ОС должна была записать 50 Мбайт в файл подкачки, и если вам нужно его прочитать, вы написали, заняли, а затем снова прочитали его 50 Мбайт вашего файла подкачки.

В случае, если память была просто mmap'ed, операционная система не будет записывать эту часть информации в файл подкачки (поскольку она знает, что эти данные идентичны самому файлу) вместо этого она просто скроет 50 МБ информации (опять же: предположим, что вы на данный момент ничего не писали) и это. Если вам когда-либо понадобится, чтобы память читалась снова, ОС будет извлекать содержимое не из файла подкачки, а из исходного файла, который вы нарисовали, поэтому, если для любой другой программы требуется 50 Мбайт свопа, они доступны. Также нет накладных расходов при работе с файлами подкачки.

Скажем, вы читаете блок данных объемом 100 Мбайт, и, согласно начальному 1Мб данных заголовка, информация, которую вы хотите, расположена со смещением 75 МБ, поэтому вам не нужно ничего между 1 ~ 74,9 МБ! Вы прочитали его только для того, чтобы сделать ваш код более простым. С помощью mmap вы будете только читать данные, к которым вы действительно обращались (округленный 4kb или размер страницы ОС, который в основном составляет 4kb), поэтому он будет читать только первый и 75-й MB. Мне очень сложно сделать более простой и эффективный способ избежать чтения диска, чем файлы mmaping. И если по какой-то причине вам нужны данные со смещением 37MB, вы можете просто использовать его! Вам не нужно снова копировать его, так как весь файл доступен в памяти (конечно, ограниченным объемом памяти вашего процесса).

Все файлы mmap'ed подкрепляются сами по себе, а не файлом swap, файл подкачки создается для предоставления данных, которые не имеют файла для резервного копирования, который обычно является данными malloc'ed или данными, которые были скопированы по файлу, но он был изменен и [не может/не должен] быть записан обратно до него, прежде чем программа на самом деле сообщает OS об этом с помощью вызова msync.

Остерегайтесь того, что вам не нужно отображать весь файл в памяти, вы можете сопоставить любую сумму (2-й аргумент является "size_t length" ), начиная с любого места (6-й arg - "off_t offset" ), но если ваш файл, вероятно, будет огромным, вы можете безопасно отображать 1 ГБ данных без страха, даже если система упаковывает только 64 МБ физической памяти, но для чтения, если вы планируете писать, вы должны быть более консервативными и отображать только материал что вам нужно.

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

Ответ 2

Основным преимуществом mmap с большими файлами является совместное использование одного и того же картографирования памяти между двумя или более файлами: если вы mmap с MAP_SHARED, он будет загружен в память только один раз для всех процессов, которые будут использовать данные с сохранение памяти.

Но AFAIK, mmap отображает весь файл в память (Здесь вы можете найти примеры того, как mmap терпит неудачу с файлами, большими, чем физическое mem + swap space.), поэтому if вы получаете доступ к файлу из одного процесса, это не поможет вам с потреблением физической памяти.

Ответ 3

Я считаю, что mmap не требует, чтобы все данные были в памяти в тот же момент - он использует кеш страницы для хранения недавно использованных страниц в памяти, а остальное на диске.

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