← Назад к вопросам

Для чего нужна виртуальная память?

2.2 Middle🔥 171 комментариев
#Linux и операционные системы

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI28 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Ответ: Виртуальная память — абстракция над физической памятью

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

Основные задачи

1. Изоляция процессов

Каждый процесс имеет собственное виртуальное адресное пространство:

Процесс 1        Процесс 2        Процесс 3
0x00000000       0x00000000       0x00000000
   Text            Text             Text
   Data            Data             Data
  Heap            Heap             Heap
  Stack           Stack            Stack
0xFFFFFFFF       0xFFFFFFFF       0xFFFFFFFF
     ↓                ↓                ↓
  Физическая память (общая)
  [раздел 1] [раздел 2] [раздел 3] ...

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

2. Переполнение физической памяти

Если RAM недостаточно, ОС может использовать swap (файл на диске):

int huge_array[1000000000];  // 4 ГБ виртуальной памяти
// Реально в памяти только используемые части
// Остальное хранится на диске и подгружается по мере необходимости

Без VM пришлось бы отказать в запуске программы.

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

ОС задаёт права доступа к страницам памяти:

Текст программы:  READ-ONLY (запретить модификацию кода)
Данные:          READ-WRITE
Stack:           READ-WRITE

Попытка записи в READ-ONLY вызывает segmentation fault.

Как это работает

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

Каждый доступ к памяти переводится аппаратурой (MMU — Memory Management Unit):

Программа: mov rax, [0x12345678]  // виртуальный адрес
    ↓
MMU проверяет таблицу страниц процесса
    ↓
Отображение: 0x12345678 виртуальный → 0xABCD1000 физический
    ↓
Чтение из физического адреса 0xABCD1000

Страницы и swap

Page table (таблица страниц):

struct PageTableEntry {
    uint32_t physical_page : 20;  // физический адрес страницы
    uint8_t flags : 12;           // биты: present, dirty, accessed, ...
};

// Пример: виртуальная страница 0 → физическая страница 5
// Если флаг present == 0: страница на диске (в swap)
// ОС загружает её в RAM и обновляет таблицу

Процесс Page Fault:

1. Программа обращается к странице на диске
2. MMU генерирует Page Fault (прерывание)
3. ОС загружает страницу в RAM
4. ОС обновляет таблицу страниц
5. Программа повторяет инструкцию

Практические следствия

Позитивные

// ✅ Можно запустить программу больше оперативной памяти
int large_buffer[2000000000];
// Если используется только часть, остаток в swap

// ✅ Безопасность между процессами
std::vector<int> secret_data;
// Другие процессы не могут прочитать

Негативные (производительность)

// ❌ Интенсивное обращение к swap — очень медленно
for (size_t i = 0; i < HUGE_SIZE; ++i) {
    // Каждое обращение может вызвать Page Fault
    // Диск медленнее RAM в 100-1000 раз
    data[i] += 1;
}

// ✅ Лучше: работать с данными, которые в памяти
for (size_t i = 0; i < CACHE_SIZE; ++i) {
    data[i] += 1;
}

Оптимизация

// mlock() — зафиксировать в физической памяти
mlock(ptr, size);  // Критичный буфер не попадёт в swap

// mmap() — отобразить файл в памяти
int fd = open("large_file.bin", O_RDONLY);
char* data = (char*)mmap(nullptr, file_size, PROT_READ, 
                         MAP_SHARED, fd, 0);

Итог

Изоляция между процессами — каждый живёт в своём адресном пространстве ✅ Переполнение RAM — можно использовать swap на диске ✅ Защита памяти — ОС контролирует доступ к страницам ✅ Транспрентность — программист пишет код, не думая о физических адресах ⚠️ Производительность — swap медленнее RAM, нужна оптимизация