linuxlab.io
Учебники▾
  • Линукс и сети
    Файловая система, процессы, TCP/IP, BGP и OSPF
    →
  • Terraform и IaC
    HCL, state, plan/apply на sandbox LocalStack
    →
  • Git и GitHub
    Объектная модель, plumbing, ветвление, GitHub Actions
    →
Все учебники →
ЦеныО платформеВойтиСоздать аккаунт
/
  • Введение
  • Уроки
  • How it works
  • Симулятор
  • База знаний
  • Собеседование
Index
Categories
All entries
Footer
linuxlab-УчебникиЦеныО платформеКонфиденциальность и куки
Copyright © 2026 LinuxLab. Все права защищены.
home/linux/kb/Процессы и ресурсы/mmap

kb/processes ── Процессы и ресурсы ── advanced

mmap - файлы и shared memory

`mmap()` маппит файл (или анонимный регион) в virtual address space процесса. Любые read/write через указатель = операции с файлом. Основа shared memory.

view as markdownaka: memory-mapping, shared-memory, memory-mapped-files

Идея

Обычно работа с файлом: open → read(fd, buf, n) в свой буфер → работа с буфером. Это копирование: page cache → user buffer.

С mmap: open → mmap(fd) → получаешь указатель → читаешь/пишешь как обычный массив. Никакого read(), ядро лениво подгружает страницы при page-fault'е.

c
int fd = open("data.bin", O_RDONLY);
void *p = mmap(NULL, len, PROT_READ, MAP_SHARED, fd, 0);
// теперь p[42] = первый прочитанный байт; страница загрузится при первом обращении

Виды mappings

File-backed:

  • MAP_PRIVATE - приватная копия. Запись не уходит в файл. Используется для загрузки бинарей/библиотек.
  • MAP_SHARED - изменения видны всем кто маппил тот же файл, в т.ч. сохраняются на диск. Это и есть shared memory через файл.

Anonymous (MAP_ANONYMOUS, без fd):

  • MAP_PRIVATE | MAP_ANONYMOUS - обычный heap; так работает malloc() для больших аллокаций
  • MAP_SHARED | MAP_ANONYMOUS - shared между fork-чайлдами

Зачем использовать

  • БД и search engines - постгрес, лусен, sqlite используют mmap для своих data-файлов. Page cache работает за них.
  • Загрузка бинарей - все ELF-файлы и .so маппятся (/proc/<pid>/maps)
  • Большие файлы random access - mmap'ить, прыгать по offset'ам. Ядро прогружает только нужные страницы.
  • IPC между процессами - MAP_SHARED на одном файле = быстрый shared region между независимыми процессами. Без копирований.
  • Memory-mapped I/O для устройств (/dev/mem)

/dev/shm - POSIX shared memory

Это tmpfs, специально для shared mappings:

c
int fd = shm_open("/myseg", O_CREAT | O_RDWR, 0600);
ftruncate(fd, 1024 * 1024);
void *p = mmap(NULL, 1024*1024, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
// → p - указатель на 1 MB; другой процесс делает shm_open("/myseg") и видит то же самое

Файл по факту в /dev/shm/myseg - можно увидеть через ls /dev/shm.

Размер /dev/shm обычно 50% RAM (tmpfs). Менять через mount:

bash
sudo mount -o remount,size=8G /dev/shm

Postgres использует /dev/shm для shared_buffers? Нет - обычно System-V shared memory или mmap файла напрямую. /dev/shm чаще используют redis, scientific computing, video processing.

Когда mmap ВРЕДЕН

  • Сетевые ФС - NFS/CIFS могут давать стрёмные результаты (consistency через сеть)
  • Огромные файлы > VAS на 32-bit - на 32-bit системах VAS = 3-4 GB
  • Append-heavy workload - постоянно расширять mmap'нутый файл дорого; обычный write() лучше
  • fault-storm - random access к холодному файлу = тысячи major faults, может задохнуться

madvise - подсказки ядру

c
madvise(addr, len, MADV_SEQUENTIAL);    // буду читать последовательно - большой readahead
madvise(addr, len, MADV_RANDOM);         // случайно - отключить readahead
madvise(addr, len, MADV_DONTNEED);       // эти страницы больше не нужны - можно выкинуть
madvise(addr, len, MADV_HUGEPAGE);       // склеить в huge pages если возможно
madvise(addr, len, MADV_DONTFORK);       // не дублировать в child при fork

Дебаг и наблюдение

bash
cat /proc/<pid>/maps              # все mappings процесса
pmap -x <pid>                      # с размерами/RSS
cat /proc/<pid>/smaps | head -30   # на каждый regional блок:
# Size:                4 kB    ← VSZ
# Rss:                 4 kB    ← реально в RAM
# Pss:                 2 kB    ← proportional (делится на shared)
# Shared_Clean:        4 kB    ← shared, чистая
# Private_Dirty:       0 kB
# Swap:                0 kB

PSS (Proportional Set Size) - лучшая метрика «реально использует»: shared библиотека на 100MB между 10 процессами даст каждому PSS = 10MB, RSS у каждого = 100MB.

Связь с другими частями

  • mmap файла + shared = page cache (page-cache). Та же страница видна и в обычном read(), и через mmap.
  • Anonymous mmap = heap = swap'ится при нехватке RAM (swap)
  • Все process-and-pid процессы разделяют libc.so.6 через MAP_PRIVATE-mappings (read-only код shared)

§ команды

bash
cat /proc/$$/maps | head

Все mappings шелла - бинарь, либы, heap, stack

bash
pmap -x <pid> | tail -1

Сводка: total VSZ + RSS процесса

bash
ls -l /dev/shm

POSIX shared memory сегменты - кто из приложений их использует

bash
cat /proc/<pid>/smaps | grep -A1 heap

RSS/PSS heap-сегмента конкретного процесса

bash
ipcs -m

Старая System-V shared memory (отдельная подсистема от mmap)

§ см. также

  • virtual-memoryVirtual memory - виртуальные адреса, page tablesКаждый процесс видит свой 64-битный virtual address space. MMU переводит виртуальные адреса в физические через page tables. Это основа изоляции и mmap.
  • page-cachePage cache - диск в памятиPage cache - кеш в RAM для содержимого файлов. Любое чтение/запись ФС идёт через него. «Used» в free выглядит большим, но page cache - это availabe.
  • file-descriptorsFile descriptors (stdin, stdout, stderr)File descriptor - целое число, через которое процесс обращается к открытому файлу/сокету/pipe. У каждого процесса 0/1/2 = stdin/stdout/stderr.
  • io-uringio_uring - third-rank async I/O syscallio_uring - shared-memory очередь между userspace и kernel. SQE submit без syscall (с SQPOLL). CQE - completion. Поддержка read/write/accept/connect/recv/send. Заменяет aio+epoll для I/O-bound сервисов. CVE 2022-2024 - не enable бездумно.
Footer
linuxlab-
Copyright © 2026 LinuxLab. Все права защищены.
Учебники
Цены
О платформе
Конфиденциальность и куки