Добавлен: 29.10.2018
Просмотров: 48003
Скачиваний: 190
1006
Глава 11. Изучение конкретных примеров: Windows 8
«зарезервированная» и «зафиксированная» страницы имеют и другие атрибуты, такие
как «читаемая», «записываемая» и «исполняемая».
Файлы подкачки
Интересный компромисс получается при назначении резервного хранилища в за-
фиксированных страницах, которые не имеют соответствия конкретным файлам. Эти
страницы используют файл подкачки (pagefile). Вопрос состоит в том, как и когда
отображать виртуальную страницу на конкретное местоположение в файле подкачки.
Простая стратегия могла быть такой: надо назначить каждой виртуальной странице
страницу в одном из файлов подкачки на диске (во время фиксации виртуальной
страницы). Это гарантирует, что всегда будет известно место для записи каждой фик-
сируемой страницы (если ее нужно будет удалить из памяти).
Windows использует синхронную (just-in-time) стратегию. Зафиксированным страни-
цам (поддерживаемым файлом подкачки) не выделяется место в файле подкачки до
того момента, когда их необходимо вытеснить в файл подкачки. Для тех страниц, кото-
рые никогда не вытесняются, дисковое пространство не выделяется. Если суммарная
виртуальная память меньше, чем имеющаяся физическая память, то файл подкачки
не нужен совсем. Это удобно для встроенных систем на базе Windows. Именно так
загружается система, поскольку файлы подкачки инициализируются после запуска
первого процесса пользовательского режима (smss.exe).
При использовании стратегии предварительного выделения общий объем используе-
мой для закрытых данных (стеки, куча, кодовые страницы копирования при записи)
виртуальной памяти ограничен размером файлов подкачки. При синхронной стратегии
общий объем виртуальной памяти может быть почти таким же большим, как сум-
марный объем файлов подкачки и физической памяти. При наличии таких больших
и дешевых (по сравнению с физической памятью) дисков экономия места не так важна,
как возможность получения повышенной производительности.
При подкачке по требованию запросы на чтение страниц с диска должны запускаться
сразу же, поскольку поток, который натолкнулся на отсутствующую страницу, не
может продолжаться до завершения этой операции подкачки страницы. Возможным
способом оптимизации подкачки страниц в память является попытка подготовки
дополнительных страниц (в этой же операции ввода-вывода). Однако те операции,
которые записывают на диск модифицированные страницы, обычно не синхрони-
зированы с выполнением потоков. Синхронная стратегия выделения пространства
в файле подкачки использует это для повышения производительности записи модифи-
цированных страниц в файл подкачки. Модифицированные страницы группируются
и записываются большими кусками. Поскольку выделение пространства в файле под-
качки не выполняется до записи страниц, то количество (требуемых для записи группы
страниц) операций поиска дорожки можно оптимизировать путем выделения страниц
файла подкачки рядом друг с другом (или даже записывая их непрерывным участком).
Когда хранящиеся в файле подкачки страницы считываются в память, они сохраняют
свое место в файле подкачки (до первой модификации). Если страница не модифици-
руется, она попадает в специальный список свободных физических страниц, называ-
емый списком резервирования (standby list), из которого она может быть взята для
повторного использования (без необходимости записывать ее обратно на диск). Если
же она модифицируется, то диспетчер памяти освобождает страницу в файле подкачки
11.5. Управление памятью
1007
и теперь единственный экземпляр страницы находится в памяти. Диспетчер памяти
делает это путем маркировки страницы «только для чтения» (после ее загрузки).
В первый раз, когда поток пытается записать в страницу, диспетчер памяти обнаружит
эту ситуацию и освободит страницу в файле подкачки, обеспечит доступ на запись
к странице, а затем даст потоку возможность повторить попытку.
Windows поддерживает до 16 файлов подкачки. Обычно они распределены по несколь-
ким дискам (для повышения производительности ввода-вывода). Все файлы имеют
некий начальный размер и максимальный размер (до которого они могут увеличить-
ся при необходимости), однако лучше создавать эти файлы максимального размера
(при инсталляции системы). Если позднее (когда диски уже будут более заполнены)
возникнет необходимость увеличения файла подкачки, то, скорее всего, новое про-
странство файла подкачки будет иметь высокую степень фрагментации (что снижает
производительность).
Операционная система отслеживает, какой виртуальной странице какая часть файла
подкачки соответствует (эта информация записывается в таблицу страниц процесса
или в таблицу страниц прототипов для объектов сегментов совместно используемых
страниц). В дополнение к тем страницам, которые поддерживаются файлом подкачки,
многие страницы процесса отображаются на обычные файлы файловой системы.
Исполняемый код и данные «только для чтения» в файле программы (в файлах EXE или
DLL) могут отображаться на пространство адресов любого использующего их процесса.
Поскольку эти страницы не могут модифицироваться, то их не нужно вытеснять в файл
подкачки, а физические страницы можно использовать повторно сразу же после того, как
все соответствия таблицы страниц будут помечены как недействительные. Когда страни-
ца опять понадобится (в будущем), диспетчер памяти прочитает ее из файла программы.
Иногда те страницы, которые вначале помечены как «только для чтения», в итоге все
же модифицируются. Например, при настройке точки останова при отладке процесса,
либо при исправлении кода с переносом его в другой адрес внутри процесса, либо
при выполнении модификаций тех страниц данных, которые были сначала совместно
используемыми. В подобных случаях Windows (как и большинство современных опе-
рационных систем) поддерживает страницу типа копирование при записи (copy-on-
write). Такие страницы вначале являются обычными отображаемыми страницами, но
когда происходит попытка модифицировать любую часть такой страницы, диспетчер
памяти создает закрытую копию для записи. Затем он обновляет таблицу страниц,
чтобы она указывала на эту закрытую копию, и дает потоку повторить запись, которая
теперь заканчивается успешно. Если эту копию позднее потребуется вытеснить, то она
будет записана в файл подкачки (а не в исходный файл).
Помимо отображения кода программ и данных из файлов EXE и DLL в память также
могут отображаться обычные файлы, что позволяет программам ссылаться на данные
из файлов (без выполнения явных операций чтения и записи). Операции ввода-вывода
все равно нужны, но они выполняются неявно диспетчером памяти (с использованием
объекта сегмента для представления соответствия между страницами памяти и блока-
ми файлов на диске).
Объекты сегментов могут вовсе не делать ссылок на файлы. Они могут ссылаться
на анонимные области памяти. При помощи установления соответствия между ано-
нимными объектами сегментов и процессами можно совместно использовать память
(без необходимости размещать файл на диске). Поскольку сегментам можно давать
1008
Глава 11. Изучение конкретных примеров: Windows 8
имена в пространстве имен NT, то процессы могут встречаться (открывая сегменты по
именам), а также дублировать описатели для объектов сегментов между процессами.
11.5.2. Системные вызовы управления памятью
Интерфейс прикладного программирования Win32 имеет несколько функций, которые
позволяют процессу явно управлять своей виртуальной памятью. Самые важные из
этих функций перечислены в табл. 11.14. Все они работают с областью, состоящей либо
из одной страницы, либо из двух и более последовательных, в виртуальном адресном
пространстве страниц. Разумеется, процессы не должны управлять своей памятью;
подкачка происходит автоматически, но эти вызовы дают процессам дополнительную
возможность и гибкость.
Таблица 11.14. Основные функции Win32 для управления виртуальной памятью
в Windows
Функция Win32
Описание
VirtualAlloc
Зарезервировать или зафиксировать область
VirtualFree
Освободить или отменить фиксирование области
VirtualProtect
Изменить защиту (чтение/запись/выполнение) для области
VirtualQuery
Сделать запрос о статусе области
VirtualLock
Сделать область резидентной (отключить для нее подкачку)
VirtuelUnlock
Сделать область подкачиваемой
CreateFileMapping
Создать отображающий файл объект и (необязательно) присвоить ему имя
MapViewOfFile
Отобразить файл (или его часть) на адресное пространство
UnmapViewOfFile
Удалить отображенный файл из адресного пространства
OpenFileMapping
Открыть ранее созданный объект отображения файла
Первые четыре функции API используются для выделения, освобождения, защиты и за-
проса областей виртуального адресного пространства. Выделенные области всегда на-
чинаются на границе 64 Кбайт (для минимизации проблем при переносе на архитектуры
будущего, страницы которых будут больше нынешних). Реальный размер выделенного
адресного пространства может быть меньше 64 Кбайт, но он должен быть кратен размеру
страницы. Следующие два вызова API дают процессу возможность зафиксировать стра-
ницы в памяти (чтобы они не вытеснялись) и отменить эту фиксацию. Такие страницы
могут потребоваться программе реального времени для того, чтобы избежать страничных
ошибок во время критичных операций. Операционная система устанавливает предел,
для того чтобы процессы не становились слишком прожорливыми. Страницы могут уда-
ляться из памяти, но только в случае вытеснения всего процесса. Когда он возвращается
назад, то все заблокированные страницы загружаются снова (после чего потоки могут
начинать работу). Несмотря на то что это не показано в табл. 11.14, Windows имеет также
функции собственного API, которые позволяют процессу обращаться к виртуальной
памяти другого процесса, для которого у него есть описатель (см. табл. 11.4).
Последние четыре функции API предназначены для управления отображенными в па-
мять файлами. Для отображения файла необходимо сначала создать объект отображения
файла (см. табл. 11.10) при помощи CreateFileMapping. Эта функция возвращает описа-
11.5. Управление памятью
1009
тель для объекта отображения файла (то есть объекта сегмента) и (необязательно) вводит
его имя в пространство имен Win32, чтобы другие процессы также могли его использо-
вать. Следующие две функции отображают и снимают отображение представлений для
объектов сегментов (из виртуального адресного пространства процесса). Последний
вызов API процесс может использовать для совместного использования отображения,
которое было создано другим процессом (при помощи CreateFileMapping), — обычно это
делается для отображения анонимной памяти. Таким образом, два или более процесса
могут совместно использовать области своих адресных пространств. Эта методика по-
зволяет им писать в некоторые области виртуальной памяти друг друга.
11.5.3. Реализация управления памятью
На процессорах х86 операционная система Windows поддерживает (для процесса)
одно линейное адресное пространство размером 4 Гбайт (с подкачкой по требова-
нию). Сегментация не поддерживается. Теоретически размер страниц может быть
степенью двойки (до 64 Кбайт). Для процессора x86 они обычно фиксированны и со-
ставляют 4 Кбайт. Кроме того, операционная система может использовать страницы
в 4 Мбайт для увеличения эффективности буфера быстрого преобразования адресов
(Translation Lookaside Buffer (TLB)) в блоке управления памятью процессора. Ис-
пользование в ядре и больших приложениях страниц размером 2 Мбайт значительно
повышает производительность (увеличивая частоту успешных обращений к TLB
и уменьшая количество проходов по таблицам страниц для поиска тех элементов,
которые отсутствуют в TLB).
Рис. 11.16. Отображенные области с их теневыми страницами на диске.
Файл lib.dll отображен на два адресных пространства одновременно
1010
Глава 11. Изучение конкретных примеров: Windows 8
В отличие от планировщика, который выбирает потоки для выполнения и не забо-
тится о процессах, диспетчер памяти полностью занимается процессами и не забо-
тится о потоках. В конце концов, именно процессы (а не потоки) владеют адресным
пространством, которым занимается диспетчер памяти. Когда выделяется область
виртуального адресного пространства (для процесса А на рис. 11.16 выделены четыре
области), диспетчер памяти создает дескриптор VAD (Virtual Address Descriptor),
в котором содержится диапазон отображенных адресов, секция представления файла
резервного хранения и смещения его отображения, а также разрешения. Когда затра-
гивается первая страница, создается каталог таблиц страниц и его физический адрес
вставляется в объект процесса. Адресное пространство полностью определяется спи-
ском его VAD. Они организованы в сбалансированное дерево (чтобы поиск дескриптора
для конкретного адреса был эффективным). Такая схема поддерживает разреженные
адресные пространства. Неиспользуемые области (между отображенными областями)
ресурсов (дисковых или памяти) не используют, поэтому они фактически свободны.
Обработка ошибок отсутствия страниц
Когда в Windows запускается процесс, многие из отображающих образы файлов EXE
и DLL страниц могут уже находиться в памяти, поскольку они используются другими
процессами. Пригодные для записи страницы образов помечены как «копирование при
записи», чтобы их можно было совместно использовать до того момента, когда их по-
надобится модифицировать. Если операционная система узнает уже выполнявшийся
ЕХЕ, то она может записать шаблон страничных ссылок (при помощи технологии,
которую компания Microsoft называет Super-Fetch). Эта технология старается забла-
говременно подкачать много нужных страниц (хотя процесс еще не получил по ним
страничные ошибки). Это снижает латентность запуска приложений (чтение страниц
с диска накладывается на выполнение инициализационного кода образов). Эта техно-
логия повышает производительность вывода на диск, поскольку дисковым драйверам
легче организовать операции чтения (чтобы уменьшить необходимое время поиска).
Этот процесс упреждающей подкачки страниц используется и во время загрузки си-
стемы, а также когда фоновое приложение выходит на передний план и при выходе
системы из гибернации.
Упреждающая подкачка страниц поддерживается диспетчером памяти, но реализована
она как отдельный компонент системы. Подкачиваемые страницы не вставляются в та-
блицу страниц процесса, вместо этого они вставляются в резервный список, из которого
могут быть быстро вставлены в процесс (без обращения к диску).
Неотображенные страницы несколько отличаются — они не инициализируются путем
чтения из файла. Вместо этого при первом обращении к неотображенной странице
диспетчер памяти предоставляет новую физическую страницу (убедившись, что ее
содержимое заполнено нулями, — из соображений безопасности). При последующих
страничных ошибках неотображенную страницу может понадобиться найти в памяти
или ее придется прочитать из файла подкачки.
Подкачка по требованию в диспетчере памяти управляется страничными ошибками.
При каждой ошибке происходит прерывание в ядро. Затем ядро строит машинно неза-
висимый дескриптор (который сообщает о происшедшем) и передает его в диспетчер
памяти исполнительного уровня. Диспетчер памяти затем проверяет обращение на
действительность. Если давшая сбой страница попадает в зафиксированную область,
то он ищет адрес в списке VAD и находит (или создает) элемент таблицы страниц