27

Первый вопрос о переполнении =)... +100 награда. Не мог придумать то, о чем я действительно заботился до сих пор:

Я действительно сыт по горло отзывчивостью рабочего стола Linux, например, http://brainstorm.ubuntu.com/item/85/ - в ситуациях с нехваткой свободной оперативной памяти или в ситуациях с высокой пропускной способностью диска система замедляется до ползать ; это абсолютно ужасно для приложений, которые требуют достойной производительности. Кроме того, пользовательский интерфейс полностью не отвечает. Сравните это, например, с OS X, где, если приложение захватывает ресурсы, всегда можно щелкнуть опцию, чтобы принудительно завершить его, тогда как в Linux я не могу даже alt-tab или переключить рабочий стол, или даже ctrl-alt-f1, чтобы получить терминал - ну, я могу, это займет около 1-2 минут за операцию.

Я использую gkrellm, чтобы видеть ситуацию, когда она разворачивается. Обычно использование памяти становится довольно высоким, или пропускная способность диска резко возрастает.

Это неплохое аппаратное обеспечение, с четырехъядерным процессором 2,6 ГГц и 4 ГБ оперативной памяти DDR2 800 МГц (было бы 6 ГБ, но из-за несовместимости аппаратного обеспечения невозможно было совмещать и сравнивать со старым набором). Эта проблема может уйти, когда я неизбежно получу больше оперативной памяти, но я не чувствую, что это суть проблемы. У меня даже есть два раздела подкачки на разных дисках.

Я чувствую, что проблема тройная:

  • беглые программы, которые занимают огромное количество памяти - для этих программ должен быть установлен закон с ограничениями на их использование.
    • (например, вкладки в Chrome, каждая из которых имеет размер 20-50 МБ, некоторые из которых могут использовать сотни МБ)
    • (например, другие программы, такие как update-db и indexers, которые мне пришлось отключить и удалить из cron, потому что они замедляли работу системы при каждом запуске и т. д.)
  • что-то ужасное, происходящее в ядре или конфликте шины, что-то вроде того, что ситуации с высокой пропускной способностью диска замедляют всю систему для сканирования (возможно, из-за подкачки важных программ)
  • ядро не назначает приоритеты пользовательскому интерфейсу или важным программам с точки зрения ресурсов, таких как память, пейджинг, даже загрузка процессора

Upvotes перейти к:

Таким образом, я ищу решение, где все такие программы уходят. В частности, я ищу решение, позволяющее пропорционально замедлять процессы, в то время как система и другие программы остаются совершенно незатронутыми и реагируют достаточно долго, чтобы что-то вручную убить. Также процесс оконного менеджера (и все остальное, что может повлиять на отзывчивость пользовательского интерфейса) должен реагировать на все обстоятельства.

В частности, я заинтригован /etc/security/limits.conf (man limits.conf), но я обеспокоен тем, что это дает контроль только для пользователя, и прокомментированные примеры в файле кажутся довольно непрозрачными с точки зрения описания или с чего начать , Я надеюсь, что limits.conf работает, но я не удивлюсь, если он даже не сработает, или если это не будет подходящим решением для моей проблемы, или настолько детализированным, насколько я пытаюсь достичь. Пределы для каждого процесса- limits.conf были бы идеальными, если снова предположить, что limit.conf работает. Я был бы рад попробовать файл limit.conf, который предоставляют люди, чтобы проверить, работает ли он, хотя я открыт для всех решений на данный момент.

Также может быть полезно иметь представление о том, как OS X поддерживает такую хорошую отзывчивость пользовательского интерфейса.

Я уже настроил мои папки /tmp и cache, чтобы они были на tmpfs , и в целом использование диска почти равно нулю.

Смутно связанные темы:

  • переполнение памяти

Не думаю, что ответы будут работать:

  • swapoff (это по-прежнему позволяет программам, занимающимся захватом памяти, избавляться от убийств, а система постоянно зависает, если память действительно плохая - приветствует любого, кто может предложить твик, который ранее вызывал OOM-killer перед заменой и предназначался для определенных программ)
  • echo ?? > /sys/.../swappiness (без заметного эффекта)
  • nice (никогда не работал)
  • ionice (разницы не заметил)
  • selinux (несовместимость программ кажется кошмаром)
  • Linux реального времени, то есть может прерывать ядро (не хочу иметь дело с компиляцией и обновлением собственного ядра; может быть, все в порядке, если оно перенесено в репозитории)
  • *

5 ответов5

6

Звучит так, будто ваша система сильно обменивается. Использование vmstat 1 может раскрыть некоторые детали - просто дайте ему запуститься в окне терминала и переключитесь на него, когда замедление начнется.

Вместо того, чтобы помещать /tmp и "cache" в tmpfs, я бы использовал обычную дисковую файловую систему, смонтированную с опцией noatime . Часто используемые данные остаются в кэше в любом случае, а старые данные могут быть записаны на диск, чтобы освободить часть оперативной памяти для приложений. Если /tmp и / или кеш становится больше, это может сильно помочь.

5

Я не разработчик ядра, но я потратил годы на то, чтобы философствовать по этому вопросу, потому что я сталкивался с таким много раз. Я на самом деле придумал метафору для всей ситуации, поэтому позвольте мне сказать вам это. Я предполагаю, что таких вещей, как "своп", не существует. В наши дни своп не имеет особого смысла с 32 ГБ ОЗУ.

Представьте себе ваш район, где вода подключена к каждому зданию через трубы, и город должен управлять мощностью. Предположим, что вы производите только 100 единиц воды в секунду (и вся неиспользованная емкость уходит в отходы, потому что у вас нет резервуаров). Каждый дом (дом = маленькое приложение, терминал, виджет часов и т.д.) Требует 1 единицу воды в секунду. Это все хорошо и хорошо, потому что вашему населению около 90 лет, поэтому все получают достаточно воды.

Теперь мэр (= вы) решите, что вы хотите открыть большой ресторан (= браузер). В этом ресторане будет несколько поваров (= вкладки браузера). Каждый повар нуждается в 1 единице воды в секунду. Вы начинаете с 10 поваров, поэтому общее потребление воды для всего района составляет 100 единиц воды, что все еще хорошо.

Теперь начинается самое интересное: вы нанимаете в свой ресторан еще одного повара, который предъявляет 101 потребность в воде, которой, очевидно, у вас нет. Вам нужно что-то сделать.

Управление водой (= ядро) имеет 3 варианта.

1. Первый вариант - просто отключить услугу для домов, которые недавно не пользовались водой. Это нормально, но если отключенный дом захочет снова использовать воду, им придется снова пройти длительный процесс регистрации. Управление может отключить несколько домов, чтобы высвободить больше водных ресурсов. На самом деле, они отключат все дома, в которых вода не использовалась в последнее время, таким образом, всегда будет доступно некоторое количество бесплатной воды.

Хотя ваш город продолжает функционировать, недостатком является то, что прогресс останавливается. Большая часть вашего времени тратится на ожидание управления водными ресурсами, чтобы восстановить ваш сервис.

Это то, что делает ядро со страницами с файловой поддержкой. Если вы запускаете большой исполняемый файл (например, Chrome), его файл копируется в память. Если в памяти недостаточно памяти или есть части, к которым недавно не обращались, ядро может отбросить эти части, потому что оно в любом случае может перезагрузить их с диска. Если это делается чрезмерно, это останавливает ваш рабочий стол, потому что все будет просто ожидать дискового ввода-вывода. Обратите внимание, что ядро также удалит много наименее недавно использованных страниц, когда вы начнете делать много операций ввода-вывода. Вот почему требуются годы, чтобы переключиться на фоновое приложение после того, как вы скопировали несколько больших файлов, таких как образы DVD.

Это самое раздражающее поведение для меня, потому что я ненавижу хип-хопы, а ты не можешь их контролировать. Было бы неплохо иметь возможность выключить его. Я думаю о чем-то вроде

sed -i 's/may_unmap = 1/may_unmap = (vm_swappiness >= 0)/' mm/vmscan.c

и затем вы можете установить vm_swappiness в -1, чтобы отключить это. Это работало довольно хорошо в моих маленьких тестах, но, увы, я не разработчик ядра, поэтому я никому не отправлял (и, очевидно, небольшая модификация выше не завершена).

2. Руководство может отклонить просьбу нового повара о воде. Это изначально звучит как хорошая идея. Однако есть два недостатка. Во-первых, есть компании, которые запрашивают много подписок на воду, хотя и не пользуются ими. Одна из возможных причин сделать это - избегать лишних разговоров с водохозяйственной службой, когда им требуется дополнительная вода. Их использование воды идет вверх и вниз в зависимости от времени дня. Например, в случае с рестораном компании нужно намного больше воды в полдень по сравнению с полуночью. Таким образом, они просят всю возможную воду, которую они могли бы использовать, но это тратит водные ресурсы в течение полуночи. Проблема заключается в том, что не все компании могут правильно предвидеть свое пиковое использование, поэтому они запрашивают намного больше в надежде, что им никогда не придется беспокоиться о запросе большего. Несмотря на то, что это затрудняет планирование мощностей для управления водными ресурсами, в обмен на это компании могут упростить и ускорить свои внутренние процессы, потому что им больше не понадобится снова работать с водными ресурсами.

Это то, что делает виртуальная машина Java: она выделяет кучу памяти при запуске, а затем работает из этого. По умолчанию ядро выделяет память только тогда, когда ваше Java-приложение фактически начинает ее использовать. Однако, если вы отключите overcommit, ядро будет серьезно относиться к резервированию. Распределение будет успешным, только если у него действительно есть ресурсы для этого.

Однако есть еще одна, более серьезная проблема с этим подходом. Допустим, одна компания начинает запрашивать одну единицу воды каждый день (а не с шагом 10). В конце концов вы достигнете состояния, в котором у вас будет 0 бесплатных юнитов. Теперь эта компания не сможет выделять больше. Это хорошо, кто заботится о больших компаниях так или иначе. Но проблема в том, что небольшие дома также не смогут запрашивать больше воды! Вы не сможете построить небольшие общественные ванные комнаты, чтобы справиться с внезапным наплывом туристов. Вы не сможете обеспечить аварийную воду для огня в близлежащем лесу.

С точки зрения компьютера: в ситуациях с очень малым объемом памяти без чрезмерной загрузки вы не сможете открыть новый xterm, вы не сможете подключиться к своей машине по ssh, вы не сможете открыть новую вкладку для поиска возможных исправления. Другими словами, отключение overcommit также делает ваш рабочий стол бесполезным, когда мало памяти.

3. Теперь вот интересный способ решения проблемы, когда компания начинает использовать слишком много воды. Управление водными ресурсами взрывает это! Буквально: он идет на сайт ресторана, бросает в него динамиты и ждет, пока он не взорвется. Это мгновенно сократит потребности города в воде, так что новые люди могут въехать, вы можете создать общественные ванные комнаты и т.д. Вы, как мэр, можете перестроить ресторан в надежде, что на этот раз потребуется меньше воды. Например, вы скажете людям не ходить в рестораны, если внутри слишком много людей (например, вы откроете меньше вкладок браузера).

Это именно то, что делает ядро, когда у него заканчиваются все параметры и ему требуется память: оно вызывает убийцу OOM. Он выбирает большое приложение (основанное на множестве эвристик) и убивает его, освобождая кучу памяти, но поддерживая отзывчивый рабочий стол. На самом деле ядро Android делает это еще более агрессивно: оно убивает наименее используемое приложение, когда памяти мало (по сравнению со стандартным ядром, которое делает это только в крайнем случае). Это называется убийцей викингов в Android.

Я думаю, что это одно из самых простых решений проблемы: у вас не так много вариантов, как это, так почему бы не преодолеть это раньше, чем позже, верно? Проблема в том, что ядро иногда выполняет довольно много работы, чтобы избежать вызова OOM killer. Вот почему вы видите, что ваш рабочий стол очень медленный, и ядро ничего не делает с этим. Но, к счастью, есть возможность вызвать убийцу ООМ самостоятельно! Сначала убедитесь, что включен магический ключ sysrq (например, echo 1 | sudo tee /proc/sys/kernel/sysrq), а затем, когда вы чувствуете, что ядру не хватает памяти, просто нажмите Alt+SysRQ, Alt+f.

Хорошо, так что все это хорошо, но вы хотите попробовать? Ситуация с низкой памятью очень просто воспроизвести. У меня есть очень простое приложение для этого. Вам нужно будет запустить его дважды. Первый запуск определит, сколько свободной оперативной памяти у вас есть, второй запуск создаст ситуацию с нехваткой памяти. Обратите внимание, что этот метод предполагает, что у вас отключен своп (например, выполните sudo swapoff -a ). Код и использование следующим образом:

// gcc -std=c99 -Wall -Wextra -Werror -g -o eatmem eatmem.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

int main(int argc, char** argv)
{
    int limit = 123456789;
    if (argc >= 2) {
        limit = atoi(argv[1]);
    }
    setbuf(stdout, NULL);
    for (int i = 1; i <= limit; i++) {
        memset(malloc(1 << 20), 1, 1 << 20);
        printf("\rAllocated %5d MiB.", i);
    }
    sleep(10000);
    return 0;
}

А вот как вы это используете:

$ gcc -std=c99 -Wall -Wextra -Werror -g -o eatmem eatmem.c
$ ./eatmem
Allocated 31118 MiB.Killed
$ ./eatmem 31110
Allocated 31110 MiB.Killed

Первый вызов обнаружил, что у нас есть 31 118 МБ свободной оперативной памяти. Поэтому я приказал приложению выделить 31 110 МБ ОЗУ, чтобы ядро не убивало его, а съело почти всю мою память. Моя система зависла: даже указатель мыши не сдвинулся с места. Я нажал Alt+SysRQ, Alt+f, и это убило мой процесс приема пищи, и система была восстановлена.

Несмотря на то, что мы рассмотрели наши варианты действий в ситуации с нехваткой памяти, наилучший подход (как и любая другая опасная ситуация) - это в первую очередь избегать этого. Есть много способов сделать это. Один из распространенных способов, которые я видел, - помещать неправильно работающие приложения (например, браузеры) в другие контейнеры, чем остальная часть системы. В этом случае браузер не сможет повлиять на ваш рабочий стол. Но сама профилактика выходит за рамки вопроса, поэтому я не буду об этом писать.

TL; DR: хотя в настоящее время нет способа полностью избежать подкачки страниц, вы можете уменьшить полную остановку системы, отключив overcommit. Но ваша система все еще будет неработоспособна в ситуации нехватки памяти, но другим способом. Независимо от вышесказанного, в ситуации нехватки памяти нажмите Alt+SysRQ, Alt+f, чтобы убить большой процесс выбора ядра. Ваша система должна восстановить свою отзывчивость через несколько секунд. Это предполагает, что у вас включен магический ключ sysrq (по умолчанию это не так).

4

Помещение всех ваших временных файлов и файлов кэша в tmpfs снижает объем свободной оперативной памяти, которую вы имеете, поэтому вы можете заставить систему переключаться быстрее, чем без нее.

Похоже, у вас есть некоторые приложения, которые полагаются на какое-то ядро или драйвер, который перегружается. Вы не будете вдаваться в подробности о том, какие типы приложений помимо браузеров и индексаторов используют, и что вы отключили индексаторы.

Вы можете попробовать переключиться на среду рабочего стола или оконный менеджер, который потребляет меньше ресурсов, например, LXDE или IceWM. На работе я использую систему Linux с установленным LXDE и ROX-Filer для минимальной настольной среды. Цель этой системы Linux - запустить VMWare Player, чтобы я мог одновременно запускать Windows XP и Windows 7. Это похоже на то, что вы говорите, и у меня не так много проблем с отзывчивостью при такой большой нагрузке, которую я испытываю. У меня нет никаких проблем с отзывчивостью в самом Linux (обычно это виртуальные машины, которые иногда заставляют меня ждать секунду, и, как ожидается, при совместном использовании 1 диска между 2 виртуальными машинами + 1 ОС), и я всегда мог приостанавливать или выключать виртуальные машины всякий раз, когда Я бы хотел. Это включает в себя запуск Firefox в Linux часто в фоновом режиме.

Так что для меня это указывает на некоторые проблемы с конкретными приложениями, которые вы используете.

DMA включен для ваших дисков? (используйте hdparm) Если вы используете полное шифрование диска, для этого требуется весь дисковый трафик, проходящий через ЦП, что сводит на нет большую часть преимуществ DMA. Результатом этого будет то, что высокий трафик диска приводит к скачкам ЦП, что замедляет работу всей системы. (РЕДАКТИРОВАТЬ: чтобы уточнить, отключение DMA ИЛИ использование dm-crypt приведет к высокой загрузке ЦП во время большого дискового трафика)

1

Это распространенная проблема с планировщиком Linux. Система замедляется, чтобы выполнить IO тяжелые действия. На самом деле не так много вещей, которые вы могли бы сделать, чтобы улучшить ситуацию, если только вы не взломали ядро :)

Может быть, они могут помочь:

http://www.phoronix.com/scan.php?page=article&item=linux_2637_video&num=1

http://www.osnews.com/story/24223/Alternative_to_the_200_Lines_Kernel_Patch_that_Does_Wonders_

0

Несмотря на то, что этому вопросу уже более двух лет, и ответ @ ypsu отличный, ситуация с системами на базе Linux, ухудшающаяся из-за нехватки ОЗУ, все еще здесь.

Вот мое наблюдение по проблеме: даже если у меня вообще нет свопинга, когда в системе недостаточно памяти, индикатор моего жесткого диска светится, так как он загружен на 100%. Учитывая этот факт, кажется, что основная причина в том, что ядро пытается освободить память, выгружая что-то, что может быть восстановлено с диска, и это, скорее всего, общие библиотеки. Поскольку приложения с графическим интерфейсом обычно имеют тонны совместно используемых библиотек, кажется, что системе может показаться, что достаточно просто выгрузить некоторые из них, но это работает только до следующей операции в пространстве пользователя, которая требует эти выгруженные библиотеки обратно. Похоже, что это наиболее вероятный сценарий, вызывающий бесконечный цикл выгрузки общих библиотек и их загрузки обратно.

Есть проект, который действует как демон пользовательского пространства, убивающий наиболее ресурсоемкие процессы, пока не стало слишком поздно: https://github.com/rfjakob/earlyoom

Кроме того, я использовал контейнеры Docker с разумными пределами памяти для приложений, требующих памяти (например, Chrome).

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .