Файл, отображаемый в памяти
Файл , отображаемый в памяти, представляет собой сегмент виртуальной памяти. [1] которому была назначена прямая побайтовая корреляция с некоторой частью файла или файловоподобного ресурса. Обычно этот ресурс представляет собой файл, который физически присутствует на диске, но также может быть устройством, объектом общей памяти или другим ресурсом, на который операционная система может ссылаться через файловый дескриптор . Когда эта корреляция между файлом и пространством памяти присутствует, она позволяет приложениям обращаться с отображаемой частью так, как если бы это была основная память.
История
[ редактировать ]ТОПС-20 ПМАП
[ редактировать ]Ранний ( ок. 1969 г. ) [2] реализацией этого был системный вызов PMAP в -20 DEC операционной системе TOPS-20 , [3] функция, используемая системой баз данных System-1022 компании Software House . [4]
SunOS 4 ммап
[ редактировать ]СанОС 4 [5] представил Unix mmap
, что позволяло программам «сопоставлять файлы в памяти». [1]
Расширяемые файлы с отображением в памяти Windows (GMMF)
[ редактировать ]Через два десятилетия после выпуска PMAP TOPS-20 в Windows NT появились расширяемые файлы с отображением в памяти (GMMF).
С " CreateFileMapping
функция требует, чтобы ей был передан размер" и изменениеразмер файла нелегко учесть, был разработан API GMMF. [6] [7] Использование GMMF требует объявляя максимальный размер файла, но при этом неиспользуемое пространство не тратится впустую.
Преимущества
[ редактировать ]Преимущество отображения файла в памяти заключается в повышении производительности ввода-вывода, особенно при использовании с большими файлами. Для небольших файлов файлы, отображенные в памяти, могут привести к пустой трате свободного пространства. [8] поскольку карты памяти всегда соответствуют размеру страницы, который обычно составляет 4 КиБ. Следовательно, файл размером 5 КиБ будет выделять 8 КиБ, и, следовательно, 3 КиБ будут потрачены впустую. Доступ к файлам, отображенным в памяти, происходит быстрее, чем использование операций прямого чтения и записи по двум причинам. Во-первых, системный вызов на порядки медленнее, чем простое изменение локальной памяти программы. Во-вторых, в большинстве операционных систем отображаемая область памяти на самом деле представляет собой ядра страничный кэш (файловый кэш), а это означает, что не требуется создавать копии в пространстве пользователя.
Некоторые файловые операции с отображением в памяти на уровне приложения также выполняются лучше, чем их физические файловые аналоги. Приложения могут получать доступ к данным в файле и обновлять их непосредственно и на месте, вместо поиска с начала файла или перезаписи всего отредактированного содержимого во временное расположение. Поскольку файл, отображаемый в памяти, обрабатывается внутри страниц, линейный доступ к файлу (как это видно, например, в хранилищах данных в неструктурированных файлах или файлах конфигурации) требует доступа к диску только тогда, когда пересекается новая граница страницы, и может записывать большие разделы памяти. файл на диск за одну операцию.
Возможным преимуществом файлов, отображаемых в памяти, является «ленивая загрузка», при которой используется небольшой объем оперативной памяти даже для очень большого файла. Попытка загрузить все содержимое файла, размер которого значительно превышает объем доступной памяти, может привести к серьезным сбоям , поскольку операционная система читает с диска в память и одновременно записывает страницы из памяти обратно на диск. Отображение памяти может не только полностью обходить файл подкачки, но также позволять загружать разделы меньшего размера по мере редактирования данных, аналогично требованию подкачки, используемой для программ.
Процесс отображения памяти обрабатывается диспетчером виртуальной памяти , который является той же подсистемой, которая отвечает за работу с файлом подкачки . Файлы, отображаемые в памяти, загружаются в память по одной странице за раз. Размер страницы выбирается операционной системой для максимальной производительности. Поскольку управление файлами подкачки является одним из наиболее важных элементов системы виртуальной памяти, загрузка разделов файла размером со страницу в физическую память обычно является очень оптимизированной системной функцией. [9]
Типы
[ редактировать ]Существует два типа файлов, отображаемых в памяти:
Сохранился
[ редактировать ]Сохраняемые файлы связаны с исходным файлом на диске. Данные сохраняются в исходный файл на диске после завершения последнего процесса. Эти файлы, отображенные в памяти, подходят для работы с очень большими исходными файлами. [10]
Несохраняющийся
[ редактировать ]Несохраняемые файлы не связаны с файлом на диске. Когда последний процесс завершил работу с файлом, данные теряются. Эти файлы подходят для создания общей памяти для межпроцессного взаимодействия (IPC). [10]
Недостатки
[ редактировать ]Основной причиной выбора файлового ввода-вывода с отображением в памяти является производительность. Тем не менее, здесь могут быть компромиссы. Стандартный подход ввода-вывода является дорогостоящим из-за накладных расходов на системные вызовы и копирования памяти. Подход с отображением в памяти имеет свою цену в виде незначительных ошибок страниц — когда блок данных загружается в страничный кэш , но еще не отображается в пространство виртуальной памяти процесса. В некоторых случаях файловый ввод-вывод с отображением в памяти может быть существенно медленнее, чем стандартный файловый ввод-вывод. [11]
данной архитектуры Другой недостаток файлов, отображаемых в памяти, связан с адресным пространством : файл, размер которого превышает адресное пространство, может одновременно отображать только части, что усложняет его чтение. Например, 32-битная архитектура, такая как Intel IA-32, может напрямую обращаться только к 4 ГиБ частям файлов размером или меньше. Отдельным программам доступен еще меньший объем адресуемого пространства — обычно от 2 до 3 ГиБ, в зависимости от ядра операционной системы. Однако этот недостаток практически устранен в современной 64-битной архитектуре.
mmap также имеет тенденцию быть менее масштабируемым, чем стандартные средства файлового ввода-вывода, поскольку многие операционные системы, включая Linux, имеют ограничение на количество ядер, обрабатывающих страничные ошибки. Чрезвычайно быстрые устройства, такие как современные твердотельные накопители NVM Express , могут вызвать серьезные проблемы с накладными расходами. [12]
Ошибки ввода-вывода в базовом файле (например, его съемный диск отключен или оптический носитель извлечен, диск заполнен при записи и т. д.) при доступе к его отображенной памяти сообщается приложению как сигналы SIGSEGV/SIGBUS в POSIX, а Структурированное исключение EXECUTE_IN_PAGE_ERROR в Windows. Весь код, обращающийся к отображаемой памяти, должен быть подготовлен к обработке этих ошибок, которые обычно не возникают при доступе к памяти.
Только аппаратные архитектуры с MMU могут поддерживать файлы, отображаемые в памяти. В архитектурах без MMU операционная система может скопировать весь файл в память при запросе на его сопоставление, но это чрезвычайно расточительно и медленно, если будет доступен только небольшой фрагмент файла, и может работать только для файлов. который поместится в доступную память.
Обычное использование
[ редактировать ]Возможно, наиболее распространенным применением файла, отображаемого в памяти, является загрузчик процессов в большинстве современных операционных систем (включая Microsoft Windows и Unix-подобные системы). Когда процесс запускается, операционная система использует файл, отображенный в памяти, для загрузки исполняемого файла. вместе со всеми загружаемыми модулями в память для выполнения. Большинство систем отображения памяти используют метод, называемый пейджингом по требованию , при котором файл загружается в физическую память подмножествами (по одной странице каждый) и только тогда, когда на эту страницу действительно есть ссылка. [13] В конкретном случае исполняемых файлов это позволяет ОС выборочно загружать только те части образа процесса, которые действительно необходимо выполнить.
Другое распространенное использование файлов, отображенных в памяти, — это совместное использование памяти между несколькими процессами. В современных операционных системах с защищенным режимом процессам обычно не разрешается доступ к пространству памяти, выделенному для использования другим процессом. (Попытка программы сделать это приводит к ошибкам недействительной страницы или нарушениям сегментации .) Существует ряд методов безопасного совместного использования памяти, и файловый ввод-вывод с отображением в памяти является одним из самых популярных. Два или более приложений могут одновременно отображать один физический файл в память и получать доступ к этой памяти. Например, операционная система Microsoft Windows предоставляет приложениям механизм сопоставления памяти общего сегмента самого файла подкачки системы и обмена данными через этот раздел.
Поддержка платформы
[ редактировать ]Большинство современных операционных систем или сред выполнения поддерживают ту или иную форму доступа к файлам, отображенным в памяти. Функция ммап () , [14] который создает сопоставление файла с учетом файлового дескриптора, начального местоположения в файле и длины, является частью спецификации POSIX , поэтому широкий спектр POSIX-совместимых систем, таких как UNIX , Linux , Mac OS X [15] или OpenVMS поддерживают общий механизм отображения файлов памяти. Операционные системы Microsoft Windows также поддерживают для этой цели группу функций API , таких как СоздатьСопоставлениеФайлов() . [16]
Некоторые бесплатные переносимые реализации файлов с отображением в памяти для Microsoft Windows и POSIX-совместимых платформ:
- Boost.Интерпроцесс, [17] в библиотеках Boost C++
- Boost.Iostreams, [18] также в библиотеках Boost C++
- FMstream [19]
- Cpp-mmf [20]
Язык программирования Java предоставляет классы и методы для доступа к файлам, отображаемым в памяти, например FileChannel
.
Язык программирования D поддерживает файлы, отображаемые в памяти, в своей стандартной библиотеке (модуль std.mmfile). [21]
В Ruby есть гем (библиотека) под названием Mmap, который реализует файловые объекты, отображаемые в памяти.
Начиная с версии 1.6, Python включает в себя mmap в стандартной библиотеке. [22] Детали модуля различаются в зависимости от того, является ли хост-платформа Windows или Unix-подобной .
Для Perl существует несколько модулей для файлов отображения памяти в CPAN , например: Сис::Ммап [23] и Файл::Карта . [24]
В среде выполнения Microsoft .NET P/Invoke можно использовать для использования файлов с отображением в памяти непосредственно через Windows API . Управляемый доступ (P/Invoke не требуется) к файлам, отображенным в памяти, был введен в версии 4 среды выполнения (см. Файлы, отображенные в памяти ). Для предыдущих версий существуют сторонние библиотеки, предоставляющие управляемые API. [25]
PHP поддерживал методы отображения памяти в ряде собственных функций доступа к файлам, таких как file_get_contents(), но удалил их в версии 5.3 (см. журнал изменений ).
Для языка программирования R в CRAN существует библиотека под названием bigmemory , которая использует библиотеку Boost и предоставляет массивы с отображением в памяти непосредственно в R. Пакет ff предлагает векторы, матрицы, массивы и кадры данных, отображаемые в памяти.
Язык программирования J поддерживает файлы с отображением в памяти по крайней мере с 2005 года. Он включает поддержку данных упакованных массивов и файлов с одним типом данных. Поддержка может быть загружена из 'data/jmf'. Механизмы баз данных Jdb и JD компании J используют файлы с отображением памяти для хранения столбцов.
Julia (язык программирования) поддерживает ввод-вывод двоичных файлов, отображаемых в памяти, через Mmap
модуль в стандартной библиотеке. [26]
Ссылки
[ редактировать ]- ^ Перейти обратно: а б Крис Зибенманн (7 июня 2018 г.). «История запутанного набора низкоуровневых способов распределения памяти в Unix» .
- ^ Разработка началась в 1969 г., отгружена в 1976 г.
- ^ «Справочное руководство по мониторингу вызовов TOPS-20» (PDF) .
- ^ «Система базы данных 1022» .
У нас был кэш PMAP для файлового ввода-вывода (например, PA1050) в расширенных разделах.
- ^ Декабрь 1988 г.
- ^ Джеффри Рихтер (октябрь 1995 г.). «Добавьте растущие файлы с отображением в памяти в ваше приложение». Системный журнал Microsoft . стр. 17–28.
- ^ Создание блока общей памяти, размер которого может увеличиваться.
- ^ «Использование mmap() для расширенного ввода-вывода файлов — BrainDump» . Архивировано из оригинала 7 августа 2011 года . Проверено 21 мая 2011 г.
- ^ , «Что могут предложить файлы, отображенные в памяти?».
- ^ Перейти обратно: а б «Файлы, отображаемые в памяти» . Сеть разработчиков Microsoft . Проверено 4 января 2016 г.
- ^ http://lists.freebsd.org/pipermail/freebsd-questions/2004-June/050371.html , прочтите в сравнении с mmap (или io и ошибками страницы), Мэтью Диллон
- ^ Папаяннис, Анастасиос; Ксантакис, Гиоргос; Салустрос, Гиоргос; Маразакис, Манолис; Билас, Ангелос (2020). Оптимизация ввода-вывода с отображением в памяти для быстрых устройств хранения данных . USENIX ATC '20. стр. 813–827.
- ^ "Пейджинг по требованию"
- ↑ Файлы с отображением памяти, заархивированные 9 февраля 2007 г. на Wayback Machine.
- ^ Apple – Mac OS X Leopard – Технология – UNIX. Архивировано 23 апреля 2009 г. на Wayback Machine.
- ^ Функция CreateFileMapping (Windows)
- ^ «Совместное использование памяти между процессами: файлы с отображением в памяти» . Boost.org.
- ^ «Файлы, отображаемые в памяти» . Boost.org.
- ^ «Файлы с отображением памяти для систем Windows и POSIX» . ИсточникФордж.
- ^ «cpp-mmf» . Гитхаб.
- ^ «std.mmfile — язык программирования D» . Цифровой Марс . Проверено 4 декабря 2011 г.
- ^ «Новые модули в версии 1.6» . Архивировано из оригинала 30 декабря 2006 года . Проверено 23 декабря 2008 г.
- ^ «Sys::Mmap Perl-модуль» .
- ^ «Файл::Map Perl-модуль» .
- ↑ DotNet. Архивировано 19 апреля 2010 г. в Wayback Machine.
- ^ «Ввод-вывод с отображением в памяти · Язык Джулии» . docs.julialang.org . Проверено 3 сентября 2023 г.