TGViewer
BashTex | Linux BashTex | Linux @bash_tex · 2.52K subscribers
Post #661 296
madvise() - как процесс подсказывает ядру, как он собирается использовать память

Когда процесс работает с большой областью памяти, ядро не всегда знает, как именно приложение будет обращаться к этим страницам.

Linux предоставляет madvise() - системный вызов, через который процесс может сообщить ядру предполагаемый характер использования памяти.

Это особенно интересно для mmap() и больших memory-mapped файлов.

▪️Последовательный доступ

Если программа собирается читать память последовательно:

madvise(addr, length, MADV_SEQUENTIAL);


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

Это позволяет иначе управлять page cache и упреждающим чтением.
Например, обработчик большого файла может пройти по нему от начала до конца вместо случайных обращений.

▪️Случайный доступ

Для случайного доступа есть:

madvise(addr, length, MADV_RANDOM);


Если приложение читает страницы в произвольном порядке, агрессивное read-ahead может оказаться бесполезным.
Подсказка позволяет ядру учитывать такой сценарий.

▪️Можно сообщить, что страницы больше не нужны

Особенно интересен:

madvise(addr, length, MADV_DONTNEED);


Процесс говорит ядру, что содержимое этой области ему сейчас не требуется.
Для анонимной памяти это может позволить освободить физические страницы. Для файлового отображения поведение связано с отображёнными страницами и page cache.
Важно: это не то же самое, что free().

Виртуальный адрес всё ещё может оставаться отображённым, но физические страницы могут быть освобождены и восстановлены при следующем обращении.

▪️Есть и подсказка WILLNEED

madvise(addr, length, MADV_WILLNEED);


Она сообщает ядру, что страницы, вероятно, скоро понадобятся.

Это может помочь подготовить данные заранее, например перед обработкой большого memory-mapped файла.
Но madvise() именно подсказывает, а не заставляет ядро выполнить конкретную стратегию.

▪️Практический сценарий
Представим программу, которая через mmap() обрабатывает несколько гигабайт файла строго последовательно.

Вместо случайного поведения с page cache она может сделать:

void *p = mmap(NULL, size,
PROT_READ,
MAP_PRIVATE,
fd, 0);

madvise(p, size, MADV_SEQUENTIAL);


Теперь приложение явно сообщает ядру характер будущего доступа.

А когда большой участок больше не нужен:

madvise(p, size, MADV_DONTNEED);


Это может уменьшить давление на память, не требуя немедленно уничтожать само отображение.

▪️Важный нюанс
madvise() не является универсальной кнопкой «ускорить память».
Эффект зависит от конкретного флага, типа mapping, версии ядра и сценария доступа.

И особенно важно не путать MADV_DONTNEED с гарантированным физическим освобождением каждой страницы: это рекомендация ядру о том, что содержимое региона можно считать ненужным.

То есть madvise() - это интерфейс, через который userspace сообщает kernel memory manager: «я примерно знаю, что собираюсь делать с этой памятью».

BashTex 📱 #bash #utils
  • 👍 3
  • 🔥 1
More from @bash_tex
  1. Oct 6, 2026Ephemeral ports - почему заканчиваются исходящие TCP-порты Когда приложение устанавливает…
  2. Oct 5, 2026name_to_handle_at() - как получить файловый объект без обычного пути В Linux обычно обраща…
  3. Oct 1, 2026flock vs fcntl - почему две блокировки одного файла могут вести себя совершенно по-разному…
  4. Sep 30, 2026DEBUG trap - как Bash выполняет код перед каждой командой В Bash есть специальный DEBUG tr…
  5. Sep 29, 2026tee + process substitution: один поток и несколько получателей Иногда нужно одновременно:…
  6. Sep 28, 2026Архитектура большого bash-скрипта Пока скрипт на 30 строк - все терпимо. На 300 строк начи…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →