← Linux: память
12 мин · средне · Урок 2 из 4

Анонимная память, page cache, RSS

Чем анонимная память отличается от файловой, что такое page cache и почему free показывает мало свободной.

Два вида страниц

Страницы памяти процесса делятся на два вида по одному признаку: стоит ли за страницей файл.

Файловая (file-backed) память — отображение файла: код программы, библиотеки, файл, открытый через mmap. У такой страницы есть копия на диске.

Анонимная (anonymous) память файлом не подкреплена. Это heap и stack процесса, данные, которые программа насчитала в ходе работы. На диске их нет нигде.

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

Page cache

Когда процесс читает файл, ядро кладёт прочитанные страницы в page cache и держит их в памяти. Повторное чтение того же файла обойдётся без диска. Запись тоже идёт через кэш: сначала в память, на диск фоном.

Отсюда главный сюрприз новичка в free:

$ free -h
              total   used   free  buff/cache  available
Mem:           7.8G   1.9G   0.3G        5.6G       5.5G

free 300 МиБ выглядит страшно, но это не беда, а норма. 5.6 ГиБ занял page cache, и ядро отдаст его мгновенно, как только память понадобится процессам: кэш-страницы reclaimable, их можно освободить в любой момент.

Смотреть надо на колонку available: это оценка, сколько памяти можно занять под новые процессы без ухода в swap. Ядро считает её из свободной памяти, реклеймируемых кэшей и watermark-порогов (MemAvailable в /proc/meminfo).

Разделяемая память и RSS

Страница может принадлежать нескольким процессам сразу. Библиотека libc загружена в память один раз, а отображена в адресные пространства сотен процессов. Это разделяемая (shared) память; сюда же относятся tmpfs и /dev/shm.

Из-за этого RSS обманчив. В /proc/<PID>/status ядро раскладывает его на части:

$ grep -E 'VmSize|VmRSS|Rss' /proc/812/status
VmSize:   720160 kB
VmRSS:     98400 kB
RssAnon:   61200 kB
RssFile:   35800 kB
RssShmem:   1400 kB

VmRSS = RssAnon + RssFile + RssShmem. Если сложить RSS всех процессов, получится больше физической памяти: разделяемые страницы посчитаются по многу раз. Честная цифра «сколько ест именно этот процесс» ближе к RssAnon.

Что важно запомнить

Файловая память подкреплена файлом, её можно выбросить и перечитать. Анонимная (heap, stack) выгружается только в swap.

Page cache держит прочитанные файлы в памяти, поэтому free мало. Смотри на available, а не на free.

VmRSS = RssAnon + RssFile + RssShmem. Сумма RSS всех процессов больше физической памяти из-за разделяемых страниц.

В следующем уроке — swap, swappiness и OOM killer.

Прошли материал до конца? Отметьте урок пройденным.