Маппинг данных

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

Итак, когда Вы создаете переменную, для нее выделяется место в памяти по определенному адресу (например ниже, с помощью дебагера в IDE, видно шестнадцатеричное число: 0x1c5e9d80, это и есть адрес в памяти).

Маппинг данных

А на этом скриншоте видны адреса всех переменных:

Маппинг данных

Когда вы создаете переменную (значение), приложение запрашивает у ОС место в куче. Наличие 32-битных адресов означает, что один экземпляр вашей программы не может использовать более 4 ГБ памяти. Два экземпляра одной программы могут выделить два разных сегмента физического адреса внутри одного сегмента виртуального адреса (0x00000000 в 0xffffffff).

Современные ОС используют виртуальное адресное пространство (ВАП, virtual address space) и процесс может работать с ячейками памяти по любым виртуальным адресам этого пространства, не "задумываясь" о том, где реально хранятся данные. Размер виртуальной памяти теоретически ограничивается разрядностью операционной системы. На практике в конкретной реализации операционной системы устанавливаются ограничения ниже теоретического предела.

В 32-разрядных системах (x86) используют для адресации 32 разрядные регистры (блоки ячеек памяти) и переменные, теоретический максимум составляет 4 ГБ (232 байт = 4 294 967 296 байт = 4 ГБ). Однако для процессов доступна только половина этой памяти – 2 ГБ , другая половина отдается системным компонентам.

В 64 разрядных системах (x64) теоретический предел равен 16 экзабайт (264 байт = 16 777 216 ТБ = 16 ЭБ). При этом процессам выделяется 8 ТБ, ещё столько же отдается системе, остальное адресное пространство (например в нынешних версиях Windows) не используется.

Реализация виртуальной памяти

Как уже отмечалось, процессу предоставляется виртуальное адресное пространство размером 4 ГБ. В Windows 2 ГБ расположенные по младшим адресам (0000 0000 – 7FFF FFFF), процесс может использовать по своему усмотрению (пользовательское ВАП), а оставшиеся два гигабайта (8000 0000 – FFFF FFFF) выделяются под системные структуры данных и компоненты (системное ВАП). Отметим, что каждый процесс имеет свое собственное пользовательское ВАП, а системное ВАП для всех процессов одно и то же.

Маппинг данных

В Linux i386 немного другие пропорции:

Маппинг данных

Виртуальные страницы

Виртуальная память делится на блоки одинакового размера – виртуальные страницы. В Windows страницы бывают большие (x86 – 4 МБ, x64 – 2 МБ) и малые (4 КБ). Физическая память (ОЗУ) также делится на страницы точно такого же размера, как и виртуальная память. Общее количество малых виртуальных страниц процесса в 32 разрядных системах равно 1 048 576 (4 ГБ / 4 КБ = 1 048 576).

Обычно процессы задействуют не весь объем виртуальной памяти, а только небольшую его часть. Соответственно, не имеет смысла (и, часто, возможности) выделять страницу в физической памяти для каждой виртуальной страницы всех процессов. Вместо этого в ОЗУ (говорят, "резидентно") находится ограниченное количество страниц, которые непосредственно необходимы процессу. Такое подмножество виртуальных страниц процесса, расположенных в физической памяти, называется рабочим набором процесса (working set).

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

Каким образом процесс узнает, где в данный момент находится требуемая страница? Для этого служат специальные структуры данных – таблицы страниц (page table).

Рассмотрим, из каких элементов состоит ВАП процесса

При запуске программы создается процесс, при этом в память загружаются:

  • код программы
  • данные программы
  • необходимые программе динамически подключаемые библиотеки (DLL)

Формируется куча (heap) – область, в которой процесс может выделять память динамическим структурам данных (т. е. структурам, размер которых заранее неизвестен, а определяется в ходе выполнения программы). По умолчанию размер кучи составляет 1 МБ, но в ходе выполнения процесса может быть изменен. Кроме того, каждому потоку предоставляется стек (stack) для хранения локальных переменных и параметров функций, также по умолчанию размером 1 МБ.

Маппинг данных

Для хранения информации о зарезервированных виртуальных страницах памяти используются дескрипторы виртуальных адресов (Virtual Address Descriptors, VAD). Каждый дескриптор содержит данные об одной зарезервированной области памяти и описывается структурой MMVAD.

Границы области определяются двумя полями – StartingVpn (начальный VPN) и EndingVpn (конечный VPN). VPN (Virtual Page Number) – это номер виртуальной страницы; страницы просто нумеруются, начиная с нулевой. Если размер страницы 4 КБ (212 байт), то VPN получается из виртуального адреса начала страницы отбрасыванием младших 12 бит (или 3 шестнадцатеричных цифр). Например, если виртуальная страница начинается с адреса 0x340000, то VPN такой страницы равен 0x340.

Дескрипторы виртуальных адресов для каждого процесса организованы в сбалансированное двоичное АВЛ дерево (AVL tree). Для этого в структуре MMVAD имеются поля указатели на левого и правого потомков: LeftChild и RightChild.

Трансляция адресов

В системе для каждого процесса поддерживается множество записей о страницах: если размер страницы 4 КБ, то чтобы хранить информацию обо всех виртуальных страницах в 32 разрядной системе требуется более миллиона записей (4 ГБ / 4 КБ = 1 048 576). Эти записи о страницах сгруппированы в таблицы страниц (Page Table), запись называется PTE (Page Table Entry). В каждой таблице содержится 1024 записи, таким образом, максимальное количество таблиц страниц для процесса – 1024 (1 048 576 / 1024 = 1024). В Windows половина от общего количества – 512 таблиц – отвечают за пользовательское ВАП, другая половина – за системное ВАП.

Таблицы страниц хранятся в виртуальной памяти (см. рис.11.2). Информация о расположении каждой из таблиц страниц находится в каталоге страниц (Page Directory), единственном для процесса. Записи этого каталога называются PDE (Page Directory Entry). Таким образом, процесс трансляции является двухступенчатым: сначала по виртуальному адресу определяется запись PDE в каталоге страниц, затем по этой записи находится соответствующая таблица страниц, запись PTE которой указывает на требуемую страницу в физической памяти.

Откуда процесс знает, где в памяти хранится каталог страниц? За это отвечает поле DirectoryTableBase структуры KPROCESS

Маппинг данных

Если опустить KPROCESS, то схема будет выглядеть немного проще:

Маппинг данных

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

Источник: 1 - 2 - 3 - 4 - 5 - 6

Оцени публикацию:
  • 0,0
Оценили: 0


Предложения и пожелания:

 

youtube.com/watch?v=7hFivbgIEqk

При полном или частичном использовании материалов данного сайта, ссылка на сайт "yapro.ru" обязательна как на источник информации.
Автоматический импорт материалов и информации с сайта запрещен.
Copyrights © 2007 - 2020 YaPro.Ru

Лебеденко Николай Николаевич
Ошибка в тексте? Выделите её мышкой и нажмите: Ctrl + Enter