Как устроена память процесса в операционной системе

«Как устроена память процесса в операционной системе» — вопрос из категории Операционные системы, который задают на 10% собеседований Python Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Операционная система выделяет каждому процессу собственное виртуальное адресное пространство, которое изолировано от других процессов. Это пространство логически разделено на несколько основных сегментов:

  1. Сегмент кода (Text Segment)

    • Содержит исполняемый машинный код программы.
    • Обычно имеет атрибут "только для чтения", чтобы предотвратить случайное изменение инструкций.
  2. Сегмент данных (Data Segment)

    • Хранит глобальные и статические переменные, которые инициализированы до начала выполнения программы.
  3. Сегмент BSS (Block Started by Symbol)

    • Хранит неинициализированные глобальные и статические переменные. ОС обнуляет эту область при запуске программы.
  4. Куча (Heap)

    • Область для динамического выделения памяти во время выполнения программы (например, создание объектов в Python, вызов malloc в C).
    • Управляется программистом или средой выполнения (например, сборщиком мусора).
    • Растёт от младших адресов к старшим.
  5. Стек (Stack)

    • Хранит локальные переменные, параметры функций и адреса возврата.
    • Работает по принципу LIFO (Last-In, First-Out). При каждом вызове функции на вершину стека помещается новый фрейм (stack frame).
    • Растёт от старших адресов к младшим, навстречу куче.

Пример в коде (концептуально):

int global_var = 10; // Хранится в сегменте данных
int global_uninitialized_var; // Хранится в BSS

void my_function() {
    int local_var = 20; // Хранится на стеке
    char* dynamic_data = (char*) malloc(100); // Память выделяется в куче
}

Эта структура обеспечивает организованное и безопасное управление памятью для каждого отдельного процесса.