← Linux: память
12 мин · средне · Урок 1 из 4

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

Зачем процессу виртуальное адресное пространство, что такое страницы, таблицы страниц и MMU.

Процесс не видит физическую память

Каждый процесс в Linux работает с виртуальной памятью: со своим отдельным адресным пространством, которое начинается с нуля и выглядит непрерывным. Физическая оперативная память при этом может быть занята кем угодно и фрагментирована как угодно. Процессу это не видно.

Такая абстракция решает две задачи. Изоляция: процесс физически не может прочитать память соседа, у него просто нет таких адресов. Удобство: программе не нужно знать, где в железе лежат её данные.

$ cat /proc/self/maps | head -4
55d3a1c00000-55d3a1c02000 r--p 00000000 08:02 393230  /usr/bin/cat
55d3a1c02000-55d3a1c07000 r-xp 00002000 08:02 393230  /usr/bin/cat
55d3a1c07000-55d3a1c0a000 r--p 00007000 08:02 393230  /usr/bin/cat
7ffd9c1f0000-7ffd9c211000 rw-p 00000000 00:00 0       [stack]

Это карта адресного пространства процесса: код, данные, стек. Все адреса здесь виртуальные.

Страницы

Память нарезана на страницы (page). Типичный размер страницы 4 КиБ. Выделение, учёт и выгрузка памяти идут страницами, а не байтами.

$ getconf PAGE_SIZE
4096

Соответствие «виртуальная страница -> физическая» хранится в таблице страниц (page table). Таблица устроена иерархически: несколько уровней, старшие биты виртуального адреса выбирают запись на каждом уровне, нижний уровень содержит физический адрес страницы.

Транслирует адреса MMU (memory management unit), аппаратный блок процессора. Чтобы не ходить по таблице на каждое обращение, свежие трансляции кэшируются в TLB. Это железо, программе оно не видно.

Память выдаётся лениво

Ядро держит в физической памяти только то, что реально нужно. Это demand paging: когда процесс просит память, ядро сначала лишь помечает диапазон адресов как выделенный. Физическая страница подставится при первом реальном обращении.

Поэтому процесс может «выделить» гигабайты и не занять почти ничего. Разница между выделенным и реально занятым видна в ps:

$ ps -o pid,vsz,rss,comm -p 812
  PID    VSZ   RSS COMMAND
  812 720160 98400 nginx

VSZ — размер виртуального адресного пространства в КиБ. RSS — сколько физической памяти процесс занимает прямо сейчас. VSZ почти всегда сильно больше RSS, и это нормально.

Что важно запомнить

Процесс видит виртуальное адресное пространство, а не физическую память. Отсюда изоляция процессов.

Память нарезана страницами, обычно по 4 КиБ. Соответствие виртуальных и физических страниц хранит таблица страниц, транслирует MMU.

Память выдаётся лениво: физическая страница подставляется при первом обращении, а не при выделении.

VSZ — виртуальный размер, RSS — реально занятая физическая память.

В следующем уроке — анонимная память, page cache и почему free показывает мало свободной памяти.

Прошли материал до конца? Отметьте урок пройденным.