[Настройка Linux, Серверное администрирование, Разработка под Linux] Почему линукс использует swap-файл, часть 2
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
Первая часть маленького «срывания покрова» о работе подсистемы виртуальной памяти, связи механизмов mmap, разделяемых библиотек и кэшей вызвало такое бурное обсуждения, что я не смог удержаться от того, чтобы не продолжить исследование на практике
Поэтому, сегодня мы сделаем… Крошечную лабораторную работу. В виде крошечной же программы на C, которую мы напишем, скомпилируем и проверим в деле — со свапом и без свапа.
Программа делает очень простую вещь — она запрашивает большой кусок памяти, обращается к нему и активно с ним работает. Чтобы не мучаться с загрузкой каких-либо библиотек, мы просто создадим большой файл, который отобразим в память так, как это делает система при загрузке разделяемых библиотек.
А вызов кода из этой «библиотеки» мы просто эмулируем чтением из такого mmap-нутого файла.
Программа сделает несколько итераций, на каждой итерации она будет параллельно обращаться к «коду» и к одному из участков большого сегмента данных.
И, чтобы не писать лишнего кода, мы определим две константы, которые определят размер «сегмента кода» и общий размер оперативной памяти:
- MEM_GBYTES — размер оперативной памяти для теста
- LIB_GBYTES — размер «кода»
Объем «данных» у нас меньше объема физической памяти:
- DATA_GBYTES = MEM_GBYTES — 2
Суммарный объем «кода» и «данных» чуть больше объема физической памяти:
- DATA_GBYTES + LIB_GBYTES = MEM_GBYTES + 1
Для теста на ноутбуке я взял MEM_GBYTES = 16, и получил следующие характеристики:
- MEM_GBYTES = 16
- DATA_GBYTES = 14 — значит «данных» будет 14GB, то есть «памяти достаточно»
- Swap size = 16GB
Текст программы
#include <sys/mman.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#define GB 1073741824l
#define MEM_SIZE 16
#define LIB_GBYTES 3
#define DATA_GBYTES (MEM_SIZE - 2)
long random_read(char * code_ptr, char * data_ptr, size_t size) {
long rbt = 0;
for (unsigned long i=0 ; i<size ; i+=4096) {
rbt += code_ptr[(8l * random() % size)] + data_ptr[i];
}
return rbt;
}
int main() {
size_t libsize = LIB_GBYTES * GB;
size_t datasize = DATA_GBYTES * GB;
int fd;
char * dataptr;
char * libptr;
srandom(256);
if ((fd = open("library.bin", O_RDONLY)) < 0) {
printf("Required library.bin of size %ld\n", libsize);
return 1;
}
if ((libptr = mmap(NULL, libsize,
PROT_READ, MAP_SHARED, fd, 0)) == MAP_FAILED) {
printf("Failed build libptr due %d\n", errno);
return 1;
}
if ((dataptr = mmap(NULL, datasize,
PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS,
-1, 0)) == MAP_FAILED) {
printf("Failed build dataptr due %d\n", errno);
return 1;
}
printf("Preparing test ...\n");
memset(dataptr, 0, datasize);
printf("Doing test ...\n");
unsigned long chunk_size = GB;
unsigned long chunk_count = (DATA_GBYTES - 3) * GB / chunk_size;
for (unsigned long chunk=0 ; chunk < chunk_count; chunk++) {
printf("Iteration %d of %d\n", 1 + chunk, chunk_count);
random_read(libptr, dataptr + (chunk * chunk_size), libsize);
}
return 0;
}
Тест без использования swap
Запрещаем swap указав vm.swappines=0 и запускаем тест
$ time ./swapdemo
Preparing test ...
Killed
real 0m6,279s
user 0m0,459s
sys 0m5,791s
Что произошло? Значение swappiness=0 отключило свап — анонимные страницы в него больше не вытесняются, то есть данные всегда в памяти. Проблема в том, что оставшихся 2GB не хватило для работающих в фоне Chrome и VSCode, и OOM-killer убил тестовую программу. А заодно нехватка памяти похоронила вкладку Chrome, в которой я писал эту статью. И мне это не понравилось — пусть даже автоматическое сохранение сработало. Я не люблю когда мои данные «хоронят».
Включенный swap
Выставляем vm_swappines = 60 (по умолчанию)
Запускаем тест:
$ time ./swapdemo
Preparing test ...
Doing test ...
Iteration 1 of 11
Iteration 2 of 11
Iteration 3 of 11
Iteration 4 of 11
Iteration 5 of 11
Iteration 6 of 11
Iteration 7 of 11
Iteration 8 of 11
Iteration 9 of 11
Iteration 10 of 11
Iteration 11 of 11
real 1m55,291s
user 0m2,692s
sys 0m20,626s
Фрагмент top:
Tasks: 298 total, 2 running, 296 sleeping, 0 stopped, 0 zombie
%Cpu(s): 0,6 us, 3,1 sy, 0,0 ni, 85,7 id, 10,1 wa, 0,5 hi, 0,0 si, 0,0 st
MiB Mem : 15670,0 total, 156,0 free, 577,5 used, 14936,5 buff/cache
MiB Swap: 16384,0 total, 12292,5 free, 4091,5 used. 3079,1 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
10393 viking 20 0 17,0g 14,2g 14,2g D 17,3 93,0 0:18.78 swapdemo
136 root 20 0 0 0 0 S 9,6 0,0 4:35.68 kswapd0
Плохой-плохой линукс!!! Он использует swap почти на 4 гигабайт хотя у него 14 гигабайт кэша и 3 гигабайта доступно! У линукса неправильные настройки! Плохой outlingo, плохие старые админы, они ничего не понимают, они сказали включить swap и теперь у меня из-за них система свапится и плохо работает. Надо отключить swap как советуют намного более молодые и перспективные интернет-эксперты, ведь они точно знают что делать!
Ну … Пусть будет так. Давайте максимально отключим свап по советам экспертов?
Тест почти без swap
Выставляем vm_swappines = 1
Это значение приведет к тому, что свапинг анонимных страниц будет производиться только если нет другого выхода.
Я верю Крису Дауну, поскольку считаю что он отличный инженер и знает что говорит, когда объясняет что swap-файл позволяет системе лучше работать. Поэтому, ожидая, что что-то пойдет «не так» и возможно система будет ужасно неэффективно работать, я заранее подстраховался и запустил тестовую программу, лимитировав её таймером, чтобы увидеть хотя бы ее аварийное завершение.
Сначала рассмотрим вывод top:
Tasks: 302 total, 1 running, 301 sleeping, 0 stopped, 0 zombie
%Cpu(s): 0,2 us, 4,7 sy, 0,0 ni, 84,6 id, 10,0 wa, 0,4 hi, 0,0 si, 0,0 st
MiB Mem : 15670,0 total, 162,8 free, 1077,0 used, 14430,2 buff/cache
MiB Swap: 20480,0 total, 18164,6 free, 2315,4 used. 690,5 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
6127 viking 20 0 17,0g 13,5g 13,5g D 20,2 87,9 0:10.24 swapdemo
136 root 20 0 0 0 0 S 17,2 0,0 2:15.50 kswapd0
Ура?! Свап используется всего лишь на 2.5 гигабайт, что почти 2 в два раза меньше чем в тесте со включенным swap (и swappiness=60). Свапа используется меньше. Свободной памяти тоже меньше. И наверное, мы можем смело отдать победу молодым экспертам. Но вот что странно — наша программа так и не смогла завершить даже 1 (ОДНОЙ!) итерации за 2 (ДВЕ!) минуты:
$ { sleep 120 ; killall swapdemo ; } &
[1] 6121
$ time ./swapdemo
Preparing test …
Doing test …
Iteration 1 of 11
[1]+ Done { sleep 120; killall swapdemo; }
Terminated
real 1m58,791s
user 0m0,871s
sys 0m23,998s
Повторим — программа не смогла завершить 1 итерацию за 2 минуты хотя в предыдущем тесте она сделала 11 итераций за 2 минуту — то есть с почти отключенным свапом программа работает более чем в 10(!) раз медленнее.
Но есть один плюс — ни одной вкладки Chrome не пострадало. И это хорошо.
Тест с полным отключением swap
Но может быть, просто «задавить» свап через swappiness недостаточно, и его надо полностью отключать? Естественно, что надо проверить и эту теорию. Мы сюда тетсты пришли провести или что
Это идеальный случай:
- унас нет свопа и все наши данные будут гарантированно в памяти
- свап не будет использоваться даже случайно, потому что его нет
И теперь наш тест завершится со скоростью молнии, старики пойдут на заслуженное ими место и будут менять картриджи — дорогу молодым.
К сожалению, результат запуска тестовой программы аналогичный — не завершилось даже одной итерации.
Вывод top:
Tasks: 217 total, 1 running, 216 sleeping, 0 stopped, 0 zombie
%Cpu(s): 0,0 us, 2,2 sy, 0,0 ni, 85,2 id, 12,6 wa, 0,0 hi, 0,0 si, 0,0 st
MiB Mem : 15670,0 total, 175,2 free, 331,6 used, 15163,2 buff/cache
MiB Swap: 0,0 total, 0,0 free, 0,0 used. 711,2 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
136 root 20 0 0 0 0 S 12,5 0,0 3:22.56 kswapd0
7430 viking 20 0 17,0g 14,5g 14,5g D 6,2 94,8 0:14.94 swapdemo
Почему это происходит
Объяснение очень простое — “сегмент кода” который мы подключаем через mmap (libptr) лежит в кэше. Поэтому когда мы запрещаем (или почти запрещаем) swap тем или иным способом, не важно каким — физическим ли отключением swap, или через vm.swappines=0|1 — это всегда заканчивается одним и тем же сценарием — вымыванием mmap’нутого файла из кэша и последующей его загрузкой с диска. А библиотеки загружаются именно через mmap, и чтобы убедиться в этом, достаточно просто сделать ls -l /proc//map_files:
$ ls -l /proc/8253/map_files/ | head -n 10
total 0
lr-------- 1 viking viking 64 фев 7 12:58 556799983000-55679998e000 -> /usr/libexec/gnome-session-binary
lr-------- 1 viking viking 64 фев 7 12:58 55679998e000-5567999af000 -> /usr/libexec/gnome-session-binary
lr-------- 1 viking viking 64 фев 7 12:58 5567999af000-5567999bf000 -> /usr/libexec/gnome-session-binary
lr-------- 1 viking viking 64 фев 7 12:58 5567999c0000-5567999c4000 -> /usr/libexec/gnome-session-binary
lr-------- 1 viking viking 64 фев 7 12:58 5567999c4000-5567999c5000 -> /usr/libexec/gnome-session-binary
lr-------- 1 viking viking 64 фев 7 12:58 7fb22a033000-7fb22a062000 -> /usr/share/glib-2.0/schemas/gschemas.compiled
lr-------- 1 viking viking 64 фев 7 12:58 7fb22b064000-7fb238594000 -> /usr/lib/locale/locale-archive
lr-------- 1 viking viking 64 фев 7 12:58 7fb238594000-7fb2385a7000 -> /usr/lib64/gvfs/libgvfscommon.so
lr-------- 1 viking viking 64 фев 7 12:58 7fb2385a7000-7fb2385c3000 -> /usr/lib64/gvfs/libgvfscommon.so
И, как мы рассматривали в первой части статьи, система в условиях фактической нехватки памяти при отключенном свапинге анонимных страниц выберет единственный вариант который её оставил владелец, отключивший свап. И этот вариант — реклейминг (освобождение) чистых страниц, занимаемых под данные mmap-нутых библиотек.
Заключение
Активное использование методики распространения программ «всё свое везу с собой» (flatpak, snap, docker image) приводит к тому, что количество кода, который подключается через mmap, существенно увеличивается.
Это может привести к тому, что использование «экстремальных оптимизаций», связанных с настройкой/отключением swap, может привести к совершенно неожиданным эффектам, потому, что swap-файл — это механизм оптимизации подсистемы виртуальной памяти в условиях memory pressure, а available memory это совсем не «неиспользуемая память», а сумма размеров кэша и свободной памяти.
Отключая swap-файл, вы не «убираете неправильный вариант», а «не оставляете вариантов»
Следует очень осторожно интерпретировать данные о потреблении памтяи процессом — VSS и RSS. Они отображают «текущее состояние» а не «оптимальное состояние».
Если вы не хотите, чтобы система использовала свап — добавьте ей памяти но не отключайте свап. Отключение свапа на пороговых уровнях сделает ситуацию значительно хуже, чем она была бы, если бы система немного отсвапилась.
P.S.: В обсуждениях регулярно задаются вопросы «а вот если включить сжатие памяти через zram...». Мне стало интересно, и я провел соответствующие тесты: если включить zram и swap, как это сделано по умолчанию в Fedora, то время работы ускоряется примерно до 1 минуты.
Но причина этого то, что страницы с нулями очень хорошо сжимаются, поэтому на самом деле данные уезжают не в swap, а хранятся в сжатом виде в оперативной памяти. Если заполнить сегмент данных случайными плохосжимаемыми данными, картина станет не такой эффектной и время работы теста опять же увеличится до 2 минут, что сравнимо (и даже чуть хуже), чем у «честного» swap-файла.
===========
Источник:
habr.com
===========
Похожие новости:
- Уязвимости в ядре Linux, затрагивающие реализации VSOCK, Futex и io_uring
- [Настройка Linux, *nix, DevOps, Разработка на Raspberry Pi] Установка docker-контейнеров c Zabbix на Raspberry Pi
- [Программирование] Mutation Driven Development
- [Дизайн игр, Компьютерное железо, Настольные компьютеры, Игры и игровые приставки] Количество VS качество: главные проблемы игр с открытым миром
- [Системное администрирование, *nix, DevOps, Микросервисы, Kubernetes] Ломаем и чиним Kubernetes
- [Разработка мобильных приложений, Тестирование мобильных приложений, Дизайн мобильных приложений] UI элементы и жесты в мобильных приложениях
- [Настройка Linux, Разработка веб-сайтов, CSS, JavaScript] Просто вертикальный монитор не значит, что я на телефоне (перевод)
- [Кодобред, Системное программирование, Разработка под Linux, Лайфхаки для гиков] Локализация своих скриптов на BASH
- [Системное администрирование, Программирование, Кодобред, *nix, Оболочки] Консольный менеджер сертификатов для JKS/PCKS12
- [PHP, Анализ и проектирование систем, NoSQL] Паспортный контроль, или Как сжать полтора гигабайта до 42 мегабайт
Теги для поиска: #_nastrojka_linux (Настройка Linux), #_servernoe_administrirovanie (Серверное администрирование), #_razrabotka_pod_linux (Разработка под Linux), #_linux, #_swap, #_optimizatsija (оптимизация), #_testirovanie (тестирование), #_nastrojka_linux (
Настройка Linux
), #_servernoe_administrirovanie (
Серверное администрирование
), #_razrabotka_pod_linux (
Разработка под Linux
)
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 12:52
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
Первая часть маленького «срывания покрова» о работе подсистемы виртуальной памяти, связи механизмов mmap, разделяемых библиотек и кэшей вызвало такое бурное обсуждения, что я не смог удержаться от того, чтобы не продолжить исследование на практике Поэтому, сегодня мы сделаем… Крошечную лабораторную работу. В виде крошечной же программы на C, которую мы напишем, скомпилируем и проверим в деле — со свапом и без свапа. Программа делает очень простую вещь — она запрашивает большой кусок памяти, обращается к нему и активно с ним работает. Чтобы не мучаться с загрузкой каких-либо библиотек, мы просто создадим большой файл, который отобразим в память так, как это делает система при загрузке разделяемых библиотек. А вызов кода из этой «библиотеки» мы просто эмулируем чтением из такого mmap-нутого файла. Программа сделает несколько итераций, на каждой итерации она будет параллельно обращаться к «коду» и к одному из участков большого сегмента данных. И, чтобы не писать лишнего кода, мы определим две константы, которые определят размер «сегмента кода» и общий размер оперативной памяти:
Объем «данных» у нас меньше объема физической памяти:
Суммарный объем «кода» и «данных» чуть больше объема физической памяти:
Для теста на ноутбуке я взял MEM_GBYTES = 16, и получил следующие характеристики:
Текст программы #include <sys/mman.h>
#include <fcntl.h> #include <string.h> #include <errno.h> #include <stdio.h> #include <stdlib.h> #define GB 1073741824l #define MEM_SIZE 16 #define LIB_GBYTES 3 #define DATA_GBYTES (MEM_SIZE - 2) long random_read(char * code_ptr, char * data_ptr, size_t size) { long rbt = 0; for (unsigned long i=0 ; i<size ; i+=4096) { rbt += code_ptr[(8l * random() % size)] + data_ptr[i]; } return rbt; } int main() { size_t libsize = LIB_GBYTES * GB; size_t datasize = DATA_GBYTES * GB; int fd; char * dataptr; char * libptr; srandom(256); if ((fd = open("library.bin", O_RDONLY)) < 0) { printf("Required library.bin of size %ld\n", libsize); return 1; } if ((libptr = mmap(NULL, libsize, PROT_READ, MAP_SHARED, fd, 0)) == MAP_FAILED) { printf("Failed build libptr due %d\n", errno); return 1; } if ((dataptr = mmap(NULL, datasize, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0)) == MAP_FAILED) { printf("Failed build dataptr due %d\n", errno); return 1; } printf("Preparing test ...\n"); memset(dataptr, 0, datasize); printf("Doing test ...\n"); unsigned long chunk_size = GB; unsigned long chunk_count = (DATA_GBYTES - 3) * GB / chunk_size; for (unsigned long chunk=0 ; chunk < chunk_count; chunk++) { printf("Iteration %d of %d\n", 1 + chunk, chunk_count); random_read(libptr, dataptr + (chunk * chunk_size), libsize); } return 0; } Тест без использования swap Запрещаем swap указав vm.swappines=0 и запускаем тест $ time ./swapdemo
Preparing test ... Killed real 0m6,279s user 0m0,459s sys 0m5,791s Что произошло? Значение swappiness=0 отключило свап — анонимные страницы в него больше не вытесняются, то есть данные всегда в памяти. Проблема в том, что оставшихся 2GB не хватило для работающих в фоне Chrome и VSCode, и OOM-killer убил тестовую программу. А заодно нехватка памяти похоронила вкладку Chrome, в которой я писал эту статью. И мне это не понравилось — пусть даже автоматическое сохранение сработало. Я не люблю когда мои данные «хоронят». Включенный swap Выставляем vm_swappines = 60 (по умолчанию) Запускаем тест: $ time ./swapdemo
Preparing test ... Doing test ... Iteration 1 of 11 Iteration 2 of 11 Iteration 3 of 11 Iteration 4 of 11 Iteration 5 of 11 Iteration 6 of 11 Iteration 7 of 11 Iteration 8 of 11 Iteration 9 of 11 Iteration 10 of 11 Iteration 11 of 11 real 1m55,291s user 0m2,692s sys 0m20,626s Фрагмент top: Tasks: 298 total, 2 running, 296 sleeping, 0 stopped, 0 zombie
%Cpu(s): 0,6 us, 3,1 sy, 0,0 ni, 85,7 id, 10,1 wa, 0,5 hi, 0,0 si, 0,0 st MiB Mem : 15670,0 total, 156,0 free, 577,5 used, 14936,5 buff/cache MiB Swap: 16384,0 total, 12292,5 free, 4091,5 used. 3079,1 avail Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 10393 viking 20 0 17,0g 14,2g 14,2g D 17,3 93,0 0:18.78 swapdemo 136 root 20 0 0 0 0 S 9,6 0,0 4:35.68 kswapd0 Плохой-плохой линукс!!! Он использует swap почти на 4 гигабайт хотя у него 14 гигабайт кэша и 3 гигабайта доступно! У линукса неправильные настройки! Плохой outlingo, плохие старые админы, они ничего не понимают, они сказали включить swap и теперь у меня из-за них система свапится и плохо работает. Надо отключить swap как советуют намного более молодые и перспективные интернет-эксперты, ведь они точно знают что делать! Ну … Пусть будет так. Давайте максимально отключим свап по советам экспертов? Тест почти без swap Выставляем vm_swappines = 1 Это значение приведет к тому, что свапинг анонимных страниц будет производиться только если нет другого выхода. Я верю Крису Дауну, поскольку считаю что он отличный инженер и знает что говорит, когда объясняет что swap-файл позволяет системе лучше работать. Поэтому, ожидая, что что-то пойдет «не так» и возможно система будет ужасно неэффективно работать, я заранее подстраховался и запустил тестовую программу, лимитировав её таймером, чтобы увидеть хотя бы ее аварийное завершение. Сначала рассмотрим вывод top: Tasks: 302 total, 1 running, 301 sleeping, 0 stopped, 0 zombie
%Cpu(s): 0,2 us, 4,7 sy, 0,0 ni, 84,6 id, 10,0 wa, 0,4 hi, 0,0 si, 0,0 st MiB Mem : 15670,0 total, 162,8 free, 1077,0 used, 14430,2 buff/cache MiB Swap: 20480,0 total, 18164,6 free, 2315,4 used. 690,5 avail Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 6127 viking 20 0 17,0g 13,5g 13,5g D 20,2 87,9 0:10.24 swapdemo 136 root 20 0 0 0 0 S 17,2 0,0 2:15.50 kswapd0 Ура?! Свап используется всего лишь на 2.5 гигабайт, что почти 2 в два раза меньше чем в тесте со включенным swap (и swappiness=60). Свапа используется меньше. Свободной памяти тоже меньше. И наверное, мы можем смело отдать победу молодым экспертам. Но вот что странно — наша программа так и не смогла завершить даже 1 (ОДНОЙ!) итерации за 2 (ДВЕ!) минуты: $ { sleep 120 ; killall swapdemo ; } &
[1] 6121 $ time ./swapdemo Preparing test … Doing test … Iteration 1 of 11 [1]+ Done { sleep 120; killall swapdemo; } Terminated real 1m58,791s user 0m0,871s sys 0m23,998s Повторим — программа не смогла завершить 1 итерацию за 2 минуты хотя в предыдущем тесте она сделала 11 итераций за 2 минуту — то есть с почти отключенным свапом программа работает более чем в 10(!) раз медленнее. Но есть один плюс — ни одной вкладки Chrome не пострадало. И это хорошо. Тест с полным отключением swap Но может быть, просто «задавить» свап через swappiness недостаточно, и его надо полностью отключать? Естественно, что надо проверить и эту теорию. Мы сюда тетсты пришли провести или что Это идеальный случай:
И теперь наш тест завершится со скоростью молнии, старики пойдут на заслуженное ими место и будут менять картриджи — дорогу молодым. К сожалению, результат запуска тестовой программы аналогичный — не завершилось даже одной итерации. Вывод top: Tasks: 217 total, 1 running, 216 sleeping, 0 stopped, 0 zombie
%Cpu(s): 0,0 us, 2,2 sy, 0,0 ni, 85,2 id, 12,6 wa, 0,0 hi, 0,0 si, 0,0 st MiB Mem : 15670,0 total, 175,2 free, 331,6 used, 15163,2 buff/cache MiB Swap: 0,0 total, 0,0 free, 0,0 used. 711,2 avail Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 136 root 20 0 0 0 0 S 12,5 0,0 3:22.56 kswapd0 7430 viking 20 0 17,0g 14,5g 14,5g D 6,2 94,8 0:14.94 swapdemo Почему это происходит Объяснение очень простое — “сегмент кода” который мы подключаем через mmap (libptr) лежит в кэше. Поэтому когда мы запрещаем (или почти запрещаем) swap тем или иным способом, не важно каким — физическим ли отключением swap, или через vm.swappines=0|1 — это всегда заканчивается одним и тем же сценарием — вымыванием mmap’нутого файла из кэша и последующей его загрузкой с диска. А библиотеки загружаются именно через mmap, и чтобы убедиться в этом, достаточно просто сделать ls -l /proc//map_files: $ ls -l /proc/8253/map_files/ | head -n 10
total 0 lr-------- 1 viking viking 64 фев 7 12:58 556799983000-55679998e000 -> /usr/libexec/gnome-session-binary lr-------- 1 viking viking 64 фев 7 12:58 55679998e000-5567999af000 -> /usr/libexec/gnome-session-binary lr-------- 1 viking viking 64 фев 7 12:58 5567999af000-5567999bf000 -> /usr/libexec/gnome-session-binary lr-------- 1 viking viking 64 фев 7 12:58 5567999c0000-5567999c4000 -> /usr/libexec/gnome-session-binary lr-------- 1 viking viking 64 фев 7 12:58 5567999c4000-5567999c5000 -> /usr/libexec/gnome-session-binary lr-------- 1 viking viking 64 фев 7 12:58 7fb22a033000-7fb22a062000 -> /usr/share/glib-2.0/schemas/gschemas.compiled lr-------- 1 viking viking 64 фев 7 12:58 7fb22b064000-7fb238594000 -> /usr/lib/locale/locale-archive lr-------- 1 viking viking 64 фев 7 12:58 7fb238594000-7fb2385a7000 -> /usr/lib64/gvfs/libgvfscommon.so lr-------- 1 viking viking 64 фев 7 12:58 7fb2385a7000-7fb2385c3000 -> /usr/lib64/gvfs/libgvfscommon.so И, как мы рассматривали в первой части статьи, система в условиях фактической нехватки памяти при отключенном свапинге анонимных страниц выберет единственный вариант который её оставил владелец, отключивший свап. И этот вариант — реклейминг (освобождение) чистых страниц, занимаемых под данные mmap-нутых библиотек. Заключение Активное использование методики распространения программ «всё свое везу с собой» (flatpak, snap, docker image) приводит к тому, что количество кода, который подключается через mmap, существенно увеличивается. Это может привести к тому, что использование «экстремальных оптимизаций», связанных с настройкой/отключением swap, может привести к совершенно неожиданным эффектам, потому, что swap-файл — это механизм оптимизации подсистемы виртуальной памяти в условиях memory pressure, а available memory это совсем не «неиспользуемая память», а сумма размеров кэша и свободной памяти. Отключая swap-файл, вы не «убираете неправильный вариант», а «не оставляете вариантов» Следует очень осторожно интерпретировать данные о потреблении памтяи процессом — VSS и RSS. Они отображают «текущее состояние» а не «оптимальное состояние». Если вы не хотите, чтобы система использовала свап — добавьте ей памяти но не отключайте свап. Отключение свапа на пороговых уровнях сделает ситуацию значительно хуже, чем она была бы, если бы система немного отсвапилась. P.S.: В обсуждениях регулярно задаются вопросы «а вот если включить сжатие памяти через zram...». Мне стало интересно, и я провел соответствующие тесты: если включить zram и swap, как это сделано по умолчанию в Fedora, то время работы ускоряется примерно до 1 минуты. Но причина этого то, что страницы с нулями очень хорошо сжимаются, поэтому на самом деле данные уезжают не в swap, а хранятся в сжатом виде в оперативной памяти. Если заполнить сегмент данных случайными плохосжимаемыми данными, картина станет не такой эффектной и время работы теста опять же увеличится до 2 минут, что сравнимо (и даже чуть хуже), чем у «честного» swap-файла. =========== Источник: habr.com =========== Похожие новости:
Настройка Linux ), #_servernoe_administrirovanie ( Серверное администрирование ), #_razrabotka_pod_linux ( Разработка под Linux ) |
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 12:52
Часовой пояс: UTC + 5