Память машины делят программы, ядро и кэш файлов. free -h показывает,
сколько чего. На машине тренажёра с 512 МиБ:
|
total |
used |
free |
shared |
buff/cache |
available |
| Mem |
458Mi |
153Mi |
5.4Mi |
964Ki |
320Mi |
304Mi |
| Swap |
0B |
0B |
0B |
|
|
|
Столбцы free
| Столбец |
Что значит |
total |
память, которой распоряжается ядро |
used |
занято программами и ядром |
free |
не занято ничем |
shared |
общая память процессов и tmpfs |
buff/cache |
кэш страниц и буферы — копии данных с диска в памяти |
available |
сколько можно отдать новым программам без swap |
total меньше 512 МиБ: часть памяти ядро забрало при загрузке под свой код
и служебные таблицы (sudo dmesg | grep Memory:).
Кэш страниц и available
Ядро держит в памяти копии прочитанных и записанных файлов — это
кэш страниц. Повторное чтение идёт из памяти, без
диска. Под кэш уходит почти вся свободная память, поэтому free на
работающей машине близок к нулю. Когда программе нужна память, ядро
вытесняет страницы кэша: их копия и так есть на диске.
available — свободная память плюс та часть кэша, которую ядро может
освободить. Это и есть запас. Опыт на машине тренажёра: прочитали много
файлов, затем сбросили кэш.
| Момент |
free |
buff/cache |
available |
после cat /usr/bin/* > /dev/null |
5.4Mi |
320Mi |
304Mi |
| после сброса кэша |
266Mi |
59Mi |
304Mi |
free вырос в 50 раз, а available не изменился: кэш и до сброса был
доступен программам. Те же числа в КиБ — в /proc/meminfo:
student@ubuntu:~$ grep -E '^(Mem|Cached)' /proc/meminfo
MemTotal: 469236 kB
MemFree: 5540 kB
MemAvailable: 311944 kB
Cached: 301900 kB
RSS — сколько памяти процесса сейчас лежит в RAM, в КиБ.
VSZ — сколько адресов он себе зарезервировал; большая часть может быть
не занята. Память процессов смотрят по RSS: столбец RSS в ps, RES в
top, VmRSS в /proc/<pid>/status.
student@ubuntu:~$ ps -o pid,rss,vsz,pmem,comm -C systemd-journald,sshd
PID RSS VSZ %MEM COMMAND
275 16792 42256 3.5 systemd-journal
773 8244 12028 1.7 sshd
Сумма RSS всех процессов бывает больше used: общие библиотеки лежат в
памяти один раз, а в RSS каждого процесса считаются целиком.
Swap
Swap — место на диске, куда ядро вытесняет редко нужные
страницы программ, чтобы освободить память. Диск во много раз медленнее
памяти: пока swap выручает, программы работают, но медленнее. Без swap при
нехватке памяти ядро сразу зовёт oom-killer.
На машине тренажёра swap нет: swapon --show ничего не печатает, в free
строка Swap: 0B 0B 0B. Swap бывает разделом диска или файлом; файл проще
добавить и убрать.
Работу swap видно в vmstat 1: si — сколько КиБ в секунду читается из
swap обратно в память, so — сколько пишется в swap. Процесс на 380 МиБ под
нехваткой памяти дал такие строки (часть столбцов опущена):
| r |
b |
swpd |
free |
si |
so |
wa |
| 0 |
1 |
131688 |
5920 |
152012 |
150756 |
56 |
| 0 |
1 |
130904 |
5096 |
135084 |
130312 |
53 |
si и so — около 150 МиБ в секунду, wa за 50: машина больше ждёт
диск, чем работает. Кто сколько держит в swap — VmSwap в
/proc/<pid>/status.
vm.swappiness
Параметр ядра vm.swappiness (от 0 до 200, в Ubuntu — 60) задаёт, насколько
охотно ядро при нехватке памяти вытесняет в swap страницы программ по
сравнению со страницами кэша. Меньше значение — дольше программы остаются
в памяти целиком. На серверах часто ставят 10.
sysctl vm.swappiness
sudo sysctl vm.swappiness=10
echo 'vm.swappiness = 10' \
| sudo tee /etc/sysctl.d/90-swappiness.conf
sudo sysctl --system
Значение из файла в /etc/sysctl.d/ переживает перезагрузку. Подробно о
параметрах ядра — sysctl.