Нехватка оперативной памяти в Linux на рабочем ПК: оптимизация и действия при зависании
На любой операционной системе часто не хватает оперативной памяти. Рассмотрим, как и сэкономить на увеличении аппаратных ресурсов машины с Linux, и продолжить более-менее комфортно пользоваться компьютером с Linux в условиях нехватки памяти.
Типична такая ситуация: есть своп (swap, раздел подкачки), который начинает использоваться при нехватке оперативной памяти, и размещен он на HDD, то есть жестком диске с низкой скоростью чтения информации. В таких ситуациях операционная система начинает тормозить, подвисает курсор мыши, сложно переключиться в соседнюю tty и т.д. Почему? Потому что планировщик ядра Linux не может выполнить запрос на какое-то действие в запущенной программе, пока не получит доступ к ее оперативной памяти, выполнить следующее действие тоже не может, образовывается очередь из запросов на чтение с диска, и система «подвисает» именно потому, что обработка очереди происходит гораздо медленнее, чем этого хочет пользователь.
Если в такой момент запустить htop или uptime , то показатель Load Average (LA) будет очень высоким, несмотря на низкую загруженность ядер процессора. Сочетание высокого Load Average и низкой загрузки процессора говорят о забитой очереди процессора.
Часто в интернете советуют изменить параметр ядра Linux vm.swappiness . Узнать его текущее значение на вашей системе можно так:
Ответ будет 60 почти наверняка. Это значит, что ядро Linux начинает свопить редко используемые страницы оперативной памяти, когда использование свободной оперативной памяти достигает 100%-60%=40%. Часто встречаются рекомендации поставить, например, vm.swappiness=10, чтобы своп не начинал использоваться, пока загрузка ОЗу не достигнет 90%. На самом деле не нужно трогать vm.swappiness, вы не умнее разработчиков ядра Linux, которые не просто так поставили 60 по умолчанию. Почему?
Представьте, что у вас всего 4 ГБ оперативной памяти, из них прямо сейчас занято 3 ГБ, vm.swappiness=10, своп на жестком диске (HDD) занят на 0%, и вы открываете тяжелый сайт в браузере, для чего требуется больше, чем имеющийся свободный 1 ГБ, например, 2 ГБ. Операционная система начинает в экстренном порядке отправлять в своп как минимум 0.5 ГБ (а по факту больше), чтобы можно было выделить браузеру необходимое количество оперативной памяти. Эта процедура становится самой приоритетной задачей, и придется пожертвовать даже движениями курсора мыши, чтобы ее выполнить как можно быстрее. Вы ждете. Проходит 5 минут, и система развисает, потому что окончила процедуру 100% загрузки очереди доступа к медленному жесткому диску, на котором размещена оперативная память (своп). При дефолтном vm.swappiness=60 редко используемые страницы памяти сбрасываются в своп заблаговременно, и резкого зависания на 5-10 минут не происходит.
UPD. В комментарии подсказывают, что это не точное описание работы vm.swappiness.
zram и приоритеты свопов
Рекомендую включить zram — прозрачное сжатие содержимого оперативной памяти. В Ubuntu это автоматизировано, достаточно установить пакет:
sudo apt install zram-config
Здесь и далее для дистрибутивов Rosa, Fedora все то же самое, но вместо zram-config —
Сервис systemd zram-config на Ubuntu будет автоматически добавлен в автозагрузку при установке пакета и запущен при перезагрузке системы. Для запуска вручную:
sudo systemctl start zram-config
sudo systemctl stop zram-config
sudo systemctl disable zram-config
sudo systemctl enable zram-config
При запуске zram-config берет число, равное 50% всего объема оперативной памяти, далее делает по одному виртуальному устройству /dev/zramN, где N начинается с 0, для каждого ядра процессора, а объем каждого /dev/zramN равен 50% всей оперативной памяти, деленному на количество ядер процессора. Так делалается для распараллеливания сжатия содержимого оперативной памяти по ядрам процессора; насколько я знаю, на современных ядрах Linux достаточно одного устройства /dev/zramN, а распараллелится оно само, но меня полностью устраивает искоробочная работа zram-config, и предпочитаю не лезть в нее руками.
Команда swapon -s выведет список всех задействованных свопов с указанием их приоритета. Первым используется тот своп, у которого приоритет выше. Если у вас уже есть дисковый своп и включен zram, то в случае с описанным выше пакетом-автокофигуратором приоритеты из коробки будут правильными. Например, у дискового свопа будет -1, а все /dev/zramN — 5. Таким образом, сначала используется zram, и только потом — диск.
Кстати, zram часто применяется на смартфонах, какую-либо на глаз заметную нагрузку на процессор при дефолтном методе сжатия lz4 он не создает.
Также приоритет свопа можно указать в /etc/fstab . Покажу на примере, как это сделано на моем рабочем компьютере с 6 ГБ ОЗУ.
$ cat /etc/fstab | grep swap # swap на SSD UUID=844fc9fb-509d-4dab-9ea5-a3d5142f76d8 none swap sw,pri=2 0 0 # swap на HDD для гибернации UUID=b643c42a-0abd-4f35-8865-7a51be5769e8 none swap sw,pri=1 0 0
Опцией монтирования pri=X заданы приоритеты свопов. Если еще включить zram, то картинка будет такой:
$ swapon -s Filename Type Size Used Priority /dev/sdb3 partition 1005564 0 2 /dev/sda2 partition 6655996 0 1 /dev/zram0 partition 690764 0 5 /dev/zram1 partition 690764 0 5 /dev/zram2 partition 690764 0 5 /dev/zram3 partition 690764 0 5
В первую очередь будет свопиться в zram, то есть сжиматься внутри оперативной памяти без использования внешнего устройства для свопа, во вторую — использовать небольшой своп на SSD. Почти никогда не будет использоваться 6 ГБ свопа на HDD, однако они понадобятся, если я захочу отправить компьютер в спящий режим в условиях большой загрузки оперативной памяти. (На самом деле у меня отключен zram).
На офисных ПК с 4 ГБ ОЗУ (Xubuntu 16.04, 17.10) всегда ставлю пакет zram-config . Chromium, по наблюдениям, на глаз, очень хорошо сжимается в оперативной памяти, в результате чего zram позволяет сделать работу намного более комфортной без модернизации железа.
Быстро вырубить программу, перегружающую ОЗУ. Запас ОЗУ для SSH
Бывает такое, что даже при vm.swappiness=60 какому-то черту, как правило, браузеру, требуется очень много оперативной памяти, и система подвисает. Решается очень просто: сочетание клавиш Alt+SysRq(PrintScreen)+F заставляет oom_killer принудительно включиться и вырубить процесс, который на момент вызова занимает больше всего памяти. Строго 1 процесс на 1 вызов, и строго обязательно что-то будет убито. Если много раз подряд нажмете, то, скорее всего, перезапустится графическая сессия. Событие убиения процесса отражается в dmesg красным цветом.
Однако эта штука, называющаяся Magic SysRq, из коробки отключена в большинстве дистрибутивов, потому что непривилегированный пользователь может убить абсолютно любой процесс. За это отчечает параметр ядра kernel.sysrq , узнать его текущее значение можно так:
Для работы Alt+SysRq+F нужно kernel.sysrq=1. Для этого отредатируем параметры ядра, расположенные в файлах /etc/sysctl.conf (обычно симлинк на /etc/sysctl.d/99-sysctl.conf) и /etc/sysctl.d/*.conf. Лучше всего создать отдельный файл:
sudo nano /etc/sysctl.d/99-dumalogiya.conf
# включить все комбинации Alt+SysRq, в т.ч. Alt+SysRq+F для принудительного вызова OOM Killer kernel.sysrq = 1 # с 8 МБ увеличим размер памяти, который будет гарантированно не занят в системе, чтобы у нас могли работать SSH и пр. vm.admin_reserve_kbytes = 60192
Нажмем Ctrl+O, Enter для сохранения.
В случае с браузером Chromium Alt+SysRq(PrintScreen)+F будет вырубать по одной вкладке, не закрывая сам браузер, что очень удобно.
Сочетания клавиш Magic SysRq перехватываются напрямую ядром Linux, поэтому работают даже когда из-за очереди процессора подвисает X-сервер.
vm.admin_reserve_kbytes — это размер оперативной памяти в килобайтах, который будет держаться гарантированно свободным для административных нужд, например, работы SSH. По умолчанию что-то около 8 МБ. Целесообразно увеличить, число 60192 почти от балды.
Я опакетил файл /etc/sysctl.d/99-dumalogiya.conf в deb-пакет dumalogiya-sysctl, который положил в свой репозиторий и ставлю на все компьютеры, очень удобно, можно централизованно обновлять конфиг, и не нужно настраивать вручную каждую машину. В качестве инструкции по сборке простых deb-пакетов «на коленке» рекомендую https://debian.pro/1390. Репозиторий создал с помощью aptly, который просто создает структуру файлов и папок внутри директории веб-сервера.
4GB оперативы и PAE (x86)
Купил себе 4GB оперативки, скомпелял ядро с CONFIG_HIGHMEM64G и CONFIG_X86_PAE, а top и gnome-system-monitor считают что памяти 3.2GB:
Это так и надо? Или я еще чего-то не сделал? Система gentoo.
мать назови — прозреваю говно чип, как в моей старой матери
чип видел только 3+ гига
что кажет POST?
POST ничего не кажет — это ноут. BIOS кажет 4096. Так как проц Core2Duo 5600, то подозреваю что все там достаточно новое.
не показатель ни то ни другое
чип давай
кстати — в бивисе нет ничего про что_то_там_remap?
# CONFIG_NOHIGHMEM is not set # CONFIG_HIGHMEM4G is not set CONFIG_HIGHMEM64G=y
Chipset Mobile Intel 945GM Express Chipset with 667-MHz front side bus
Настроек в биосе фиг да ни фига. Ничего похожего нету.
закрывай тему — это непотребство больше 3+ гига тебе не отдаст
соболезную
morse@morsebook ~ $ grep HIGHMEM /usr/src/linux/.config # CONFIG_NOHIGHMEM is not set # CONFIG_HIGHMEM4G is not set CONFIG_HIGHMEM64G=y CONFIG_HIGHMEM=y
И что, даже если я честную x86-64 поставлю не поможет?
Не поможет, там контроллер памяти 32-битовый.
man 945 штеуд-чип, неосилятор топиков
>Используй ядро x86_64
Если у человек использует PAE, значит, у него 32 бита
На моем компе PAE видит 3.8 из 4.
>Если у человек использует PAE, значит, у него 32 бита
Какая-нибудь видеоинтеграшка откушала 256 метров.
Что ты этим хотел сказать? Что ядро с PAE не загрузится на машине с процессором x86_64?
> Не поможет, там контроллер памяти 32-битовый.
Ни разу не видел, чтобы были такие ограничения, если x86_64, вообще, поддерживается. Так что почти готов спорить, что будет 4Gb с 64-разрядным ядром.
2morse: загрузись с LiveCD x86_64, да посмотри. Делов-то.
Дело не в PAE и не в x64. Часть адресов из диапазона от 3 до 4GB занята устройствами. Умные материнки умеют маппить эту память на неиспользуемые адреса. Глупые — нет.
Т.е. при включённом PAE или на x64:
если ты поставишь 4Gb будет видно 3 с копейками.
если ты поставишь 8Gb будет видно 7 с копейками.
если ты поставишь 16Gb будет видно 15 с копейками.
> Ни разу не видел, чтобы были такие ограничения, если x86_64, вообще, поддерживается.
Погугли intel 945 memory limit и подумай. Хинт — важна поддержка не только процессором, но и контроллером памяти.
> Погугли intel 945 memory limit и подумай.
Зачем мне гугль, если я неоднократно видел реальную картину ? Не уверен, что именно с 945, но аналогичную. Но хорошо, у меня именно такой компьютер в личном пользовании: 82945G/Intel(R) Celeron(R) CPU 3.20GHz
Завтра возьму 4Gb и грузанусь с LiveCD. Отпишусь. 🙂
> Т.е. при включённом PAE или на x64:
Не верно. PAE — это PAE, а x64 — это x64. Например, на 5000 серверном интеловском чипсете PAE тоже не даёт 4Gb при 4-х установленных.
Да это уже не так принципиально. Все равно не буду я себе x64 ставить. Ленивый я.
> Да это уже не так принципиально. Все равно не буду я себе x64 ставить. Ленивый я.
А вот тут есть тонкий момент: вообще, как говорят, можно только поставить ядро x86_64. Но сам я такого не делал.
> Погугли intel 945 memory limit и подумай. Хинт — важна поддержка не
только процессором, но и контроллером памяти.
Ладно, уговорил. Действительно, контроллер там ущербный. Вообще это полный маразм — делать такое ограничение для чипсета, рассчитанного на использование 64-разрядных процессоров. Однако, и правда, случается.
Получилось 3350264 total для x86_64.
> делать такое ограничение для чипсета,
Да, одно время Интел этим увлекался. Экономили биты и транзисторы в контроллере памяти. Так, например, 815-й чипсет не поддерживал больше 512 метров оперативки.
Не знаю насчет маразма, а вот то, что они об этом пишут только в дебрях тех документации — просто свинство. Везде куда ни глянь — «up to 4GB memory support»
> Так, например, 815-й чипсет не поддерживал больше 512 метров оперативки.
С 815, как раз, больше понятно. Бюджетное решение, да и памяти в десктопах тогда столько надо было далеко не всегда. C x86_64 ситуация совсем другая. Большого преимущества для конечного пользователя от этого, как правило, не видно, пока памяти мало. Получается, что 945-ый чипсет просто не нужен: можно было сэкономить и на новых процессорах — просто не покупать. Как переходный вариант для разработчика ПО рассматривать — тоже плохо, так как тут память лишней не бывает.