Какие виды памяти процесса существуют в Linux/Unix-системах?

«Какие виды памяти процесса существуют в Linux/Unix-системах?» — вопрос из категории Linux и ОС, который задают на 25% собеседований C/C++ Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

В адресном пространстве процесса в Linux/Unix традиционно выделяют несколько сегментов памяти:

  1. Сегмент кода (Text Segment) Содержит исполняемые инструкции программы (машинный код). Обычно имеет права только на чтение и выполнение (r-x), чтобы предотвратить случайную модификацию кода.

  2. Сегмент данных (Data Segment)

    • Инициализированные данные (.data) — глобальные и статические переменные с явно заданным начальным значением.
    • Неинициализированные данные (.bss) — глобальные и статические переменные, инициализируемые нулём. На диске не хранятся, экономя место.
      int global_init = 5;      // Попадёт в .data
      static int static_var;    // Попадёт в .bss (инициализируется 0)
  3. Куча (Heap) Область для динамического выделения памяти во время выполнения программы. Управляется вручную программистом с помощью malloc/free (C) или new/delete (C++). Растёт в сторону увеличения адресов. Неуправляемая куча — частая причина утечек памяти и фрагментации.

    int* arr = new int[100]; // Выделение в куче
    // ...
    delete[] arr;            // Обязательное освобождение
  4. Стек (Stack) Используется для хранения локальных переменных, аргументов функций, информации о вызовах (адреса возврата, сохранённые регистры). Выделение и освобождение происходит автоматически. Имеет ограниченный размер (часто 8 МБ), переполнение приводит к краху (Stack Overflow). Растёт в сторону уменьшения адресов.

    void foo() {
        int localVar = 10; // Переменная размещается на стеке
    } // При выходе из функции память для localVar автоматически освобождается
  5. Отображённая в память область (Memory-mapped Region) Файлы или устройства, отображённые в адресное пространство процесса с помощью системного вызова mmap. Позволяет работать с файлом как с массивом в памяти, что эффективно для больших файлов или разделяемой памяти между процессами (IPC).