Открыть сервис

Страничная адресация

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

История

Концепция страничной адресации была впервые предложена в 1961 году в Манчестерском университете (Великобритания) в рамках проекта Atlas. Система Atlas использовала однобитовые ассоциативные регистры для ускорения трансляции адресов, что стало прообразом современных буферов ассоциативной трансляции (TLB). В 1970-х годах страничная адресация была реализована в операционных системах Multics и Unix, а также в процессорах Intel 8086 (через сегментно-страничную схему). С 1980-х годов страничная адресация стала стандартом для всех универсальных процессоров, включая архитектуры x86, ARM, RISC-V и PowerPC.

Принцип работы

Виртуальные и физические адреса

Виртуальный адрес, генерируемый процессором, делится на две части: номер виртуальной страницы (Virtual Page Number, VPN) и смещение внутри страницы (offset). Размер страницы обычно составляет 4 КБ (4096 байт) в архитектуре x86, но может быть 2 МБ, 1 ГБ или другими значениями (большие страницы, huge pages). Физический адрес также делится на номер физического кадра (Physical Frame Number, PFN) и смещение. Смещение в виртуальном и физическом адресе совпадает, так как страницы и кадры имеют одинаковый размер.

Таблицы страниц

Таблица страниц (page table) — это структура данных, хранящаяся в физической памяти, которая для каждой виртуальной страницы содержит запись (Page Table Entry, PTE). PTE включает:

  • Номер физического кадра (PFN) — адрес, куда отображается страница.
  • Бит присутствия (present bit) — указывает, находится ли страница в физической памяти.
  • Бит изменения (dirty bit) — фиксирует, была ли страница записана (используется для подкачки).
  • Бит обращения (accessed bit) — указывает, обращались ли к странице (используется для алгоритмов замещения).
  • Бит разрешения (read/write/execute) — контролирует доступ.
  • Бит пользовательского режима (user/supervisor) — определяет, может ли процесс обращаться к странице.

В современных системах таблицы страниц имеют многоуровневую структуру (например, 4 уровня в x86-64: PML4, PDPT, PD, PT) для экономии памяти, так как большая часть виртуального адресного пространства не используется. Каждый уровень хранит указатели на следующий уровень, а на последнем уровне находятся PTE.

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

Процессор при обращении к памяти выполняет следующие шаги:

  1. Извлекает VPN из виртуального адреса.
  2. Проходит по многоуровневой таблице страниц, начиная с корневого каталога (адрес которого хранится в регистре CR3 в x86).
  3. На каждом уровне считывает запись, проверяет бит присутствия. Если страница отсутствует (page fault), генерируется исключение, и операционная система загружает страницу с диска.
  4. На последнем уровне получает PFN, объединяет его со смещением и формирует физический адрес.

Для ускорения трансляции используется буфер ассоциативной трансляции (TLB) — кэш, хранящий недавно использованные соответствия VPN→PFN. Если TLB попадание (hit), трансляция занимает 1-2 такта; если промах (miss), требуется до 4-5 обращений к памяти (для 4-уровневой таблицы).

Классификация и виды

По размеру страниц

  • Стандартные страницы (4 КБ) — наиболее распространённый размер, используется в большинстве ОС (Linux, Windows, macOS).
  • Большие страницы (2 МБ, 1 ГБ) — применяются для приложений с большими объёмами памяти (базы данных, виртуализация, научные расчёты), уменьшают количество записей в TLB и снижают накладные расходы на управление таблицами.
  • Смешанные страницы — современные процессоры поддерживают несколько размеров одновременно, что позволяет ОС выбирать оптимальный размер для каждого региона памяти.

По способу управления

  • Одноуровневая таблица — простая, но неэффективная для больших адресных пространств (использовалась в ранних системах).
  • Многоуровневая таблицастандарт для 64-битных архитектур, позволяет экономить память за счёт того, что неиспользуемые части адресного пространства не требуют выделения таблиц.
  • Инвертированная таблица страниц — хранит одну запись на каждый физический кадр, а не на каждую виртуальную страницу; используется в некоторых архитектурах (например, PowerPC) для экономии памяти при малом объёме физической памяти.

По типу адресации

  • Страничная адресация без сегментации — чистая страничная модель, где виртуальное адресное пространство едино (например, в ARM64).
  • Сегментно-страничная адресация — комбинация сегментации и страничной адресации (например, в x86-32 в защищённом режиме), где сначала виртуальный адрес преобразуется в линейный через сегмент, а затем линейный — в физический через страницы.

Устройство и характеристики

Аппаратная поддержка

Страничная адресация требует аппаратной поддержки со стороны процессора. Ключевые компоненты:

  • Блок управления памятью (MMU) — аппаратный модуль, выполняющий трансляцию адресов.
  • TLB — быстрый кэш для трансляций, обычно реализованный как ассоциативная память (CAM) или кэш с прямым отображением.
  • Регистры управления — содержат адрес корневой таблицы страниц (например, CR3 в x86, TTBR в ARM).
  • Исключения page fault — генерируются при отсутствии страницы, нарушении прав доступа или ошибках таблицы.

Программное управление

Операционная система отвечает за:

  • Создание и обновление таблиц страниц при создании процессов.
  • Обработку page fault — загрузку страниц с диска, выделение физических кадров, сброс грязных страниц.
  • Замещение страниц (алгоритмы LRU, FIFO, Clock) — выбор страниц для выгрузки на диск при нехватке памяти.
  • Управление TLB — сброс (flush) TLB при переключении контекста или изменении таблиц.

Производительность

Основные факторы, влияющие на производительность страничной адресации:

  • Размер TLB — чем больше TLB, тем выше вероятность попадания. Современные процессоры имеют TLB на 32–1024 записи.
  • Размер страницы — большие страницы уменьшают количество записей в TLB, но увеличивают фрагментацию и потери памяти.
  • Многоуровневость таблиц — увеличивает латентность при промахе TLB, но экономит память.
  • Алгоритмы замещения — влияют на частоту page fault и время доступа к диску.

Применение

Виртуальная память

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

Защита памяти

Биты в PTE (read/write/execute, user/supervisor) позволяют операционной системе контролировать доступ к памяти. Например, страницы кода могут быть только для чтения и выполнения, а страницы данных — для чтения и записи. Это предотвращает выполнение кода из стека (NX-бит) и защищает ядро от пользовательских процессов.

Разделение памяти

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

Виртуализация

В системах виртуализации (например, KVM, VMware) страничная адресация используется для изоляции гостевых операционных систем. Гостевая ОС управляет своими таблицами страниц, а гипервизор использует аппаратную поддержку вложенных страниц (Intel EPT, AMD NPT) для трансляции гостевых физических адресов в реальные физические.

Примеры

Linux

В Linux страничная адресация реализована через архитектурно-зависимый код. Для x86-64 используется 4-уровневая таблица (PML4, PDPT, PD, PT). Размер страницы по умолчанию — 4 КБ, но поддерживаются большие страницы (2 МБ через hugetlbfs, 1 ГБ через transparent huge pages). ОС использует алгоритм замещения на основе LRU (list of active/inactive pages) и поддерживает свопинг.

Windows

В Windows (NT-ядро) страничная адресация аналогична Linux, но с некоторыми отличиями: таблицы страниц имеют 4 уровня (PML4, PDPT, PD, PT), размер страницы — 4 КБ. Windows поддерживает большие страницы (2 МБ) через API VirtualAlloc с флагом MEM_LARGE_PAGES. Управление памятью включает рабочие наборы (working sets) и алгоритм замещения на основе тактов (clock algorithm).

Критика и ограничения

Фрагментация

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

Накладные расходы

Многоуровневые таблицы страниц требуют нескольких обращений к памяти при промахе TLB, что увеличивает латентность доступа. Для ускорения используются TLB, предвыборка (prefetching) и аппаратные walker (автоматический обход таблиц).

Уязвимости

Страничная адресация может быть использована для атак, таких как Meltdown и Spectre, которые эксплуатируют спекулятивное выполнение и TLB для получения доступа к защищённой памяти. В ответ на это были разработаны аппаратные и программные меры (KPTI — Kernel Page Table Isolation).

Сложность управления

Операционная система должна поддерживать сложные алгоритмы замещения, управления TLB и обработки page fault, что увеличивает сложность кода ядра и может приводить к ошибкам.

Интересные факты

  • В архитектуре x86-64 виртуальное адресное пространство составляет 48 бит (256 ТБ), хотя физические адреса могут быть до 52 бит (4 ПБ). Оставшиеся 16 бит виртуального адреса должны быть копией 47-го бита (sign extension) для обеспечения совместимости.
  • Первый коммерческий процессор с поддержкой страничной адресации — Intel 80386 (1985 год), который ввёл защищённый режим с 32-битной адресацией и страничным управлением.
  • В некоторых операционных системах (например, FreeBSD) используется алгоритм замещения страниц на основе двухсторонней очереди (two-handed clock), который эффективно работает при высокой нагрузке на память.

Источники

  • Andrew S. Tanenbaum, Herbert Bos. «Современные операционные системы» (4-е издание), 2015.
  • Daniel P. Bovet, Marco Cesati. «Понимание ядра Linux» (3-е издание), 2005.
  • Intel Corporation. «Intel 64 and IA-32 Architectures Software Developer's Manual», Volume 3A: System Programming Guide, 2023.
  • ARM Limited. «ARM Architecture Reference Manual ARMv8-A», 2022.
  • John L. Hennessy, David A. Patterson. «Компьютерная архитектура: количественный подход» (6-е издание), 2017.

BFOmetr — база данных и аналитика по компаниям России.

На главную BFOmetr →