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

Что такое Page fault?

2.0 Middle🔥 151 комментариев
#Linux и администрирование

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

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

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

Что такое Page Fault (отказ страницы)

Page fault (страничный отказ, отсутствие страницы) — это тип аппаратного исключения (exception), возникающего в системах с виртуальной памятью, когда процесс пытается обратиться к странице памяти, которая в данный момент отсутствует в оперативной памяти (RAM). Это не ошибка в программировании, а нормальный механизм работы современных операционных систем, позволяющий эффективно управлять памятью.

Механизм возникновения и обработки

Когда процесс обращается к виртуальному адресу, MMU (Memory Management Unit) транслятор адресов проверяет наличие соответствующей физической страницы в RAM. Если страница отсутствует, происходит page fault. Управление передается обработчику прерываний операционной системы (в Linux это часть ядра), который выполняет следующую последовательность действий:

  1. Определение типа отказа: Система проверяет, является ли обращение легальным (адрес в пределах виртуального адресного пространства процесса) и имеет ли процесс необходимые права доступа (чтение, запись, выполнение).
  2. Поиск данных: Ядро ищет требуемую страницу на устройстве вторичного хранения (чаще всего в области swap на диске, но также может быть в файле, отображенном в память — memory-mapped file).
  3. Освобождение места: Если в RAM нет свободных страниц, алгоритм замещения страниц (например, LRU — Least Recently Used) выбирает "жертву" для выгрузки. Если страница-"жертва" была изменена ("грязная" — dirty), она сначала записывается на диск.
  4. Загрузка и обновление: Требуемая страница загружается с диска в освобожденный физический кадр. Таблица страниц (Page Table) процесса обновляется: запись для данной виртуальной страницы теперь указывает на новый физический адрес, и флаг присутствия (present bit) устанавливается в 1.
  5. Возобновление выполнения: Процесс возобновляет выполнение с команды, вызвавшей прерывание. Теперь доступ к памяти будет успешным, так как страница находится в RAM.

Классификация Page Fault

Существует три основных типа:

  • Minor (Soft) Page Fault (Мягкий отказ): Запрашиваемая страница уже находится в памяти, но не отображена в таблице страниц данного процесса (например, была загружена для другого процесса или является частью разделяемой библиотеки). Обработчик просто обновляет запись в таблице страниц. Это самый быстрый и дешевый тип.
  • Major (Hard) Page Fault (Жесткий отказ): Страница действительно отсутствует в оперативной памяти и должна быть загружена с диска (из swap или файла). Это самый затратный тип, так как включает операции ввода-вывода (I/O), которые на порядки медленнее доступа к RAM.
  • Invalid Page Fault (Недопустимый отказ): Процесс обращается к несуществующему или защищенному адресу (например, пытается записать в сегмент кода). Это приводит к отправке сигнала процессу (в Linux — SIGSEGV, Segmentation Fault), что обычно ведет к его аварийному завершению.

Значение для DevOps и мониторинга

Понимание page fault критически важно для инженера DevOps по нескольким причинам:

  • Диагностика проблем производительности: Высокий уровень major faults (pgmajfault в Linux) — прямой индикатор нехватки оперативной памяти (OOM — Out Of Memory). Процессы начинают активно "свопиться" на диск, что вызывает лавинообразное падение производительности (явление thrashing).

    # Мониторинг page faults с помощью утилиты `ps`
    ps -eo pid,comm,minflt,majflt,pmem,pcpu --sort=-majflt | head -20
    
    # Просмотр статистики из /proc (пример для процесса с PID 1234)
    cat /proc/1234/stat | awk '{print $10, $12}'  # minflt и majflt
    
  • Настройка и планирование ресурсов: Анализ паттернов page fault помогает правильно определять лимиты памяти для контейнеров (Docker --memory, Kubernetes resources.limits.memory) и виртуальных машин, предотвращая деградацию производительности из-за своппинга.

  • Оптимизация приложений: Выявление процессов с аномально высоким количеством minor faults может указывать на проблемы с локальностью данных или неоптимальную работу с памятью в самом приложении (например, частое выделение/освобождение больших массивов).

Пример на практике

Рассмотрим простой код на C, который гарантированно вызовет major page fault при первом обращении к массиву:

#include <stdio.h>
#include <stdlib.h>

int main() {
    // Выделяем буфер размером 100 МБ. На этом этапе физическая память может не выделяться
    // (ленивое выделение — lazy allocation).
    size_t size = 100 * 1024 * 1024; // 100 MB
    char *buffer = (char *)malloc(size);

    if (buffer == NULL) {
        perror("malloc failed");
        return 1;
    }

    // ПЕРВОЕ обращение к каждой странице этого буфера вызовет major page fault,
    // так как ОС фактически выделит физические страницы.
    for (size_t i = 0; i < size; i += 4096) { // Страница обычно 4 КБ
        buffer[i] = 'A';
    }

    // Последующие обращения к тем же страницам отказов не вызовут.
    for (size_t i = 0; i < size; i += 4096) {
        buffer[i] = 'B';
    }

    free(buffer);
    return 0;
}

Заключение

Page fault — это фундаментальный механизм, лежащий в основе работы виртуальной памяти. Для DevOps-инженера ключевой задачей является не устранение их полностью (это невозможно), а мониторинг и анализ, особенно количества major faults. Резкий рост этого показателя — четкий сигнал для масштабирования памяти, оптимизации приложения или пересмотра выделенных ресурсов. Инструменты вроде vmstat, sar, pidstat и метрики из /proc являются основными средствами для наблюдения за этой областью.

Что такое Page fault? | PrepBro