Иерархия памяти и виртуальная память
Почему память не одна, а целая пирамида — и как ОС даёт каждой программе собственный «бесконечный» простор.
Виртуальная память — абстракция, при которой каждый процесс видит собственное непрерывное адресное пространство, не зная, где его данные лежат физически.
Иерархия памяти
Быстрая память дорогая, дешёвая — медленная. Совместить «быстро и много» нельзя, поэтому память устроена пирамидой: чем выше, тем быстрее и меньше.
| Уровень | Скорость | Объём |
| Регистры процессора | самая высокая | байты |
| Кэш L1/L2/L3 | очень высокая | КБ–МБ |
| Оперативная память (RAM) | высокая | ГБ |
| SSD/диск | низкая | ТБ |
Разрыв огромен: обращение к регистру — доли наносекунды, к диску — миллионы наносекунд. Поэтому так важно держать «горячие» данные повыше в пирамиде.
Принцип локальности
Пирамида работает благодаря локальности — программы обращаются к памяти не случайно:
- Временная локальность. Если данные понадобились, скоро понадобятся снова (переменная в цикле).
- Пространственная локальность. Если обратились к адресу, скоро обратятся к соседнему (элементы массива подряд).
Кэш и подкачка опираются именно на это: подгружают данные «с запасом» в быструю память, рассчитывая, что они скоро понадобятся.
Проблемы без виртуальной памяти
Если бы программы работали с физическими адресами напрямую, возникли бы беды:
- Программа могла бы прочитать или испортить память другой программы.
- Адреса пришлось бы «прибивать» при компиляции — две программы не ужились бы в одной памяти.
- Нельзя было бы запустить программу, которой нужно больше памяти, чем есть физически.
Идея виртуальной памяти
Решение — дать каждому процессу виртуальное адресное пространство: он считает, что владеет непрерывной памятью от нуля до огромного адреса, целиком своей. На самом деле эти виртуальные адреса транслируются в физические специальным механизмом (MMU — блок управления памятью), а ОС ведёт таблицы соответствия.
Что это даёт:
- Изоляцию. Виртуальные адреса разных процессов ведут в разную физическую память.
- Иллюзию большой памяти. Можно адресовать больше, чем есть физически, — недостающее лежит на диске (подкачка).
- Удобство. Программе не нужно знать, где она реально загружена.
Аналогия: камера хранения
Вы сдаёте вещи и получаете номерок (виртуальный адрес). Где именно лежит ваш чемодан на складе (физический адрес) — не ваша забота, это знает только работник по своей таблице. Двум клиентам можно выдать «номерок 5», и это будут разные ячейки — потому что таблицы у них разные.
Эффект локальности в цифрах
Покажем, как попадания в кэш (благодаря локальности) ускоряют доступ. Сравним среднее время при разной доле попаданий.
cache_ns = 1 # доступ к кэшу, нс
ram_ns = 100 # доступ к RAM, нс
for hit_rate in (0.0, 0.5, 0.9, 0.99):
avg = hit_rate * cache_ns + (1 - hit_rate) * ram_ns
print(f"Попаданий {hit_rate*100:5.1f}% -> среднее время доступа {avg:6.2f} нс")
Вывод:
Попаданий 0.0% -> среднее время доступа 100.00 нс Попаданий 50.0% -> среднее время доступа 50.50 нс Попаданий 90.0% -> среднее время доступа 10.90 нс Попаданий 99.0% -> среднее время доступа 1.99 нс
При 99% попаданий доступ почти как к кэшу — вот почему локальность так ценна.
Итог
- Память — пирамида: регистры, кэш, RAM, диск; выше — быстрее и меньше.
- Иерархия работает благодаря локальности (временной и пространственной).
- Виртуальная память даёт каждому процессу своё непрерывное адресное пространство.
- Виртуальные адреса транслируются в физические через MMU и таблицы ОС.
- Это даёт изоляцию, иллюзию большой памяти и удобство для программ.