Виртуальные адресные пространства

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

Доступ к памяти с помощью виртуальных адресов имеет несколько преимуществ.

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

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

  • Виртуальные адреса, используемые различными процессами, изолированы. Код в одном процессе не может изменить физическую память, используемую другим процессом или операционной системой.

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

  • 32-разрядный процесс обычно имеет виртуальное адресное пространство в диапазоне от 2 гигабайтов 0x00000000 до 0x7FFFFFFF.

  • 64-разрядный процесс в 64-разрядной версии Windows имеет виртуальное адресное пространство в диапазоне 128 терабайт 0x000'00000000–0x7FFF'FFFFFFFF.

Диапазон виртуальных адресов иногда называют диапазоном виртуальной памяти. Дополнительные сведения см. в разделе Ограничения памяти и адресного пространства.

На следующей схеме показаны некоторые ключевые функции виртуальных адресных пространств.

Схема, показывающая виртуальные адресные пространства для двух 64-разрядных процессов, Notepad.exe и MyApp.exe.

На схеме показаны виртуальные адресные пространства для двух 64-разрядных процессов: Notepad.exe и MyApp.exe. Каждый процесс имеет собственное виртуальное адресное пространство в диапазоне от 0x000'00000000 до 0x7FF'FFFFFFFF. Каждый блок с затенениями представляет одну страницу (размером 4 килобайта) виртуальной или физической памяти. Процесс Блокнота использует три смежные страницы виртуальных адресов, начиная с 0x7F7'93950000. Однако эти три смежные страницы виртуальных адресов сопоставляется с несмежными страницами в физической памяти. Кроме того, оба процесса используют страницу виртуальной памяти, начиная с 0x7F7'93950000, но эти виртуальные страницы сопоставляют с разными страницами физической памяти.

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

Такие процессы, как Notepad.exe и MyApp.exe выполняются в пользовательском режиме. Основные компоненты операционной системы и многие драйверы работают в более привилегированном режиме ядра. Дополнительные сведения о режимах процессора см. в разделе Пользовательский режим и режим ядра.

Каждый процесс пользовательского режима имеет собственное частное виртуальное адресное пространство, но весь код, который выполняется в режиме ядра, использует одно виртуальное адресное пространство, называемое системным пространством. Виртуальное адресное пространство для процесса пользовательского режима называется пространством пользователя.

В 32-разрядной версии Windows общий объем доступного виртуального адресного пространства составляет 2^32 байта (4 гигабайта). Как правило, нижние 2 гигабайта используются для пространства пользователя, а верхние 2 гигабайта — для системного пространства.

Схема, иллюстрирующая разделение общего доступного виртуального адресного пространства в 32-разрядной версии Windows на пользовательское и системное пространство.

В 32-разрядной версии Windows можно указать (во время загрузки), что для пользовательского пространства доступно более 2 гигабайт. Однако это означает, что для системного пространства доступно меньше виртуальных адресов. Вы можете увеличить размер пользовательского пространства до 3 гигабайт, оставив только 1 гигабайт для системного пространства. Чтобы увеличить размер пользовательского пространства, используйте BCDEdit /set increaseuserva.

В 64-разрядной версии Windows теоретический объем виртуального адресного пространства составляет 2^64 байта (16 эксабайтов), но фактически используется лишь небольшая часть 16-exabyte диапазона.

Код, выполняемый в пользовательском режиме, может получить доступ к пространству пользователя, но не к системе. Это ограничение не позволяет коду пользовательского режима считывать или изменять защищенные структуры данных операционной системы. Код, выполняемый в режиме ядра, может получить доступ как к пространству пользователя, так и к системе. Это значит, что код, выполняемый в режиме ядра, может получить доступ к системным пространствам и виртуальному диапазону адресов текущего процесса в пользовательском режиме.

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

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

  2. Подпрограмма драйвера устройства, работающая в режиме ядра, запускает операцию чтения и возвращает управление вызывающей функции.

  3. Позже устройство прерывает текущий выполняемый поток, чтобы указать, что операция чтения завершена. Подпрограммы драйвера в режиме ядра обрабатывают прерывание в этом произвольном потоке, который принадлежит произвольному процессу.

  4. На этом этапе драйвер не должен записывать данные на начальный адрес, предоставленный программой пользовательского режима на шаге 1. Этот адрес находится в виртуальном адресном пространстве процесса, который инициировал запрос, что, скорее всего, не совпадает с текущим процессом.

Выгружаемый и невыгружаемый пул

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

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

Схема, показывающая разницу между выделением памяти в выстраившемся пуле.

Узлы устройств и стеки устройств

Пользовательский режим и режим ядра