Книга: 2.Внутреннее устройство Windows (гл. 5-7)

Разделяемая память и проецируемые файлы

Разделяемая память и проецируемые файлы

Как и большинство современных операционных систем, Windows поддерживает механизм разделения памяти. Разделяемой (shared memory) называется память, видимая более чем одному процессу или присутствующая в виртуальном адресном пространстве более чем одного процесса. Например, если два процесса используют одну и ту же DLL, есть смысл загрузить ее код в физическую память лишь один раз и сделать ее доступной всем процессам, проецирующим эту DLL (рис. 7–1).


Каждый процесс поддерживает закрытые области памяти для хранения собственных данных, но программные инструкции и страницы немодифицируемых данных в принципе можно использовать совместно с другими процессами. Как вы еще увидите, такой вид разделения реализуется автоматически, поскольку страницы кода в исполняемых образах проецируются с атрибутом «только для выполнения», а страницы, доступные для записи, — с атрибутом «копирование при записи» (copy-on-write) (см. раздел «Копирование при записи» далее в этой главе).

Для реализации разделяемой памяти используются примитивы диспетчера памяти, объекты «раздел», которые в Windows API называются объектами «проекция файла» (file mapping objects). Внутренняя структура и реализация этих объектов описывается в разделе «Объекты-разделы» далее в этой главе.

Этот фундаментальный примитив диспетчера памяти применяется для проецирования виртуальных адресов в основной памяти, страничном файле или любых других файлах, к которым приложение хочет обращаться так, будто они находятся в памяти. Раздел может быть открыт как одним процессом, так и несколькими; иначе говоря, объекты «раздел» вовсе не обязательно представляют разделяемую память.

Объект «раздел» может быть связан с открытым файлом на диске (который в этом случае называется проецируемым) или с переданной памятью (для ее разделения). Разделы, проецируемые на переданную память, называются разделами, поддерживаемыми страничными файлами (page file backed sections), так как при нехватке памяти их страницы перемещаются в страничный файл. (Однако Windows может работать без страничного файла, и тогда эти разделы «поддерживаются» физической памятью.) Разделяемые переданные страницы, как и любые другие страницы, видимые в пользовательском режиме (например, закрытые переданные страницы), всегда обнуляются при первом обращении к ним.

Для создания объекта «раздел» используется Windows-функция Create-FileMapping, которой передается описатель проецируемого файла (или INVALID_HANDLE_VALUE в случае раздела, поддерживаемого страничным файлом), а также необязательные имя и дескриптор защиты. Если разделу присвоено имя, его может открыть другой процесс вызовом OpenFileMapping. Кроме того, вы можете предоставить доступ к объектам «раздел» через наследование описателей (определив при открытии или создании описателя, что он является наследуемым) или их дублирование (с помощью Duplicate-Handle). Драйверы также могут манипулировать объектами «раздел» через функции ZwOpenSection, ZwMapViewOfSection и ZwUnmapViewOfSection.

Объект «раздел» может ссылаться на файлы, длина которых намного превышает размер адресного пространства процесса. (Если раздел поддерживается страничным файлом, в нем должно быть достаточно места для размещения всего раздела.) Используя очень большой объект «раздел», процесс может проецировать лишь необходимую ему часть этого объекта, которая называется представлением (view) и создается вызовом функции MapViewOfFiIe с указанием проецируемого диапазона. Это позволяет процессам экономить адресное пространство, так как на память проецируется только представление объекта «раздел».

Windows-приложения могут использовать проецирование файлов для упрощения ввода-вывода в файлы на диске, просто делая их доступными в своем адресном пространстве. Приложения — не единственные потребители объектов «раздел»: загрузчик образов использует их для проецирования в память исполняемых образов, DLL и драйверов устройств, а диспетчер кэша — для доступа к данным кэшируемых файлов. (Об интеграции диспетчера кэша с диспетчером памяти см. в главе 11.) O реализации разделов совместно используемой памяти мы расскажем потом.

ЭКСПЕРИМЕНТ: просмотр файлов, проецируемых в память

Просмотреть спроецированные в память файлы для какого-либо процесса позволяет утилита Process Explorer от Sysinternals. Для этого настройте нижнюю секцию ее окна на режим отображения DLL. (Выберите View, Lower Pane View, DLLs.) Заметьте, что это не просто список DLL, — здесь представлены все спроецированные в память файлы в адресном пространстве процесса. Некоторые являются DLL, один из них — файлом выполняемого образа (EXE), а другие элементы списка могут представлять файлы данных, проецируемые в память. Например, на следующей иллюстрации показан вывод Process Explorer применительно к процессу Microsoft PowerPoint, в адресное пространство которого загружен документ PowerPoint.


Для поиска спроецированных в память файлов щелкните Find, DLL. Это удобно, когда нужно определить, какие процессы используют DLL, которую вы пытаетесь заменить.

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

Оглавление книги

Оглавление статьи/книги

Генерация: 1.379. Запросов К БД/Cache: 3 / 1
поделиться
Вверх Вниз