История изменений
Исправление AEP, (текущая версия) :
я в целом не понимаю почему при исчерпании ОЗУ Линукс делает лапки кверху
Все достаточно просто, если разобрать вопрос по частям. Во-первых надо понять, как Linux работает с кодом и данными, которые в исполняемых файлах и библиотеках. Во-вторых, разобраться, что такое out of memory в понимании ядра. В-третьих, склеить эти два куска новых знаний. Поехали. Для простоты, будем считать, что swap’а нет, но это непринципиально.
В Linux есть два вида страниц памяти (переупрощаю): анонимная память и файловый кеш. Приложение может попросить кусок памяти и использовать на чтение и запись, как ему заблагорассудится - это анонимная память. А еще приложение может сказать «mmap», т.е. «дай мне фальшивый кусок памяти, а при попытках из него прочитать - давай мне данные вот из этого файла». При этом по факту ненужные куски файла не читаются. Ядро кеширует прочитанное в ОЗУ. За счет этого файлового кеша, пока он не сброшен, по производительности такая фальшивая память не отличается от обычной. Так вот, программы и библиотеки всегда грузятся через mmap.
Теперь разбираемся, что ядро делает, если памяти не хватает. Такое встречается сплошь и рядом, ведь ядро агрессивно кеширует прочитанные файлы. Так вот, первый шаг - это определение набора страниц памяти, которые можно просто выбросить без последствий. Как правило, это страницы файлового кеша, которые после чтения не были изменены. Их всегда можно прочитать заново, и никто ничего не заметит - если не следит за временем.
А теперь скомбинируем эти знания. Пользователь открывает кучу вкладок в браузере и грузит тяжелые сайты. Сайты ложатся в анонимную память, код браузера - в файловый кеш. В конечном итоге, когда пользователь застрял на pikabu и стал прокручивать вниз, памяти стало не хватать. Ядро нашло давно не использовавшуюся страницу файлового кеша - это часть кода браузера, отвечающая за переключение вкладок. Ядро его и выбросило, а освободившуюся память перепрофилировало под анонимную, чтобы там хранить очередной пост.
Затем пользователь таки переключает вкладку с pikabu на gmail. Ой, а код переключения вкладок из памяти выброшен! Надо вернуть его на место путем чтения с диска, пока никто не заметил… а вот некуда, так как свободных страниц нет. Ну, есть код отображения картинок, он большой и ненужный, давайте часть его выкинем, а код для переключения вкладок прочитаем. Переключили вкладку. Ой, а сейчас надо рисовать картинку, а код выброшен! Надо этот код загрузить, а что-то ненужное выбросить. Вот есть вторая половина распаковщика картинок, давайте выбросим ее, а первую половину прочитаем с диска. Ура, прочитали и выполнили… вот только опять приходится выполнять выброшенный код. Да ничего страшного, так и будем барахтаться по-собачьи, без паники, прогресс есть (!!!), убивать пользовательские процессы нет необходимости. Вот только получился процессор, работающий по факту на частоте 1 MHz, а остальное время ждущий, пока прострекочет диск, и пользователь, с точки зрения которого все зависло.
Официальное решение - MGLRU, которое уже в официальном ядре. По факту оно тоже не работает. Из наиболее рабочего в настоящее время могу посоветовать prelockd, в который корне пресекает ситуацию, когда приходится выбрасывать «ненужный» код в надежде прочитать его повторно.
Исправление AEP, :
я в целом не понимаю почему при исчерпании ОЗУ Линукс делает лапки кверху
Все достаточно просто, если разобрать вопрос по частям. Во-первых надо понять, как Linux работает с кодом и данными, которые в исполняемых файлах и библиотеках. Во-вторых, разобраться, что такое out of memory в понимании ядра. В-третьих, склеить эти два куска новых знаний. Поехали. Для простоты, будем считать, что swap’а нет, но это непринципиально.
В Linux есть два вида страниц памяти (переупрощаю): анонимная память и файловый кеш. Приложение может попросить кусок памяти и использовать на чтение и запись, как ему заблагорассудится - это анонимная память. А еще приложение может сказать «mmap», т.е. «дай мне фальшивый кусок памяти, а при попытках из него прочитать - давай мне данные вот из этого файла». При этом по факту ненужные куски файла не читаются. Ядро кеширует прочитанное в ОЗУ. За счет этого файлового кеша, пока он не сброшен, по производительности такая фальшивая память не отличается от обычной. Так вот, программы и библиотеки всегда грузятся через mmap.
Теперь разбираемся, что ядро делает, если памяти не хватает. Такое встречается сплошь и рядом, ведь ядро агрессивно кеширует прочитанные файлы. Так вот, первый шаг - это определение набора страниц памяти, которые можно просто выбросить без последствий. Как правило, это страницы файлового кеша, которые после чтения не были изменены. Их всегда можно прочитать заново, и никто ничего не заметит - если не следит за временем.
А теперь скомбинируем эти знания. Пользователь открывает кучу вкладок в браузере и грузит тяжелые сайты. Сайты ложатся в анонимную память, код браузера - в файловый кеш. В конечном итоге, когда пользователь застрял на pikabu и стал прокручивать вниз, памяти стало не хватать. Ядро нашло давно не использовавшуюся страницу файлового кеша - это часть кода браузера, отвечающая за переключение вкладок. Ядро его и выбросило, а освободившуюся память перепрофилировала под анонимную, чтобы там хранить очередной пост.
Затем пользователь таки переключает вкладку с pikabu на gmail. Ой, а код переключения вкладок из памяти выброшен! Надо вернуть его на место путем чтения с диска, пока никто не заметил… а вот некуда, так как свободных страниц нет. Ну, есть код отображения картинок, он большой и ненужный, давайте часть его выкинем, а код для переключения вкладок прочитаем. Переключили вкладку. Ой, а сейчас надо рисовать картинку, а код выброшен! Надо этот код загрузить, а что-то ненужное выбросить. Вот есть вторая половина распаковщика картинок, давайте выбросим ее, а первую половину прочитаем с диска. Ура, прочитали и выполнили… вот только опять приходится выполнять выброшенный код. Да ничего страшного, так и будем барахтаться по-собачьи, без паники, прогресс есть (!!!), убивать пользовательские процессы нет необходимости. Вот только получился процессор, работающий по факту на частоте 1 MHz, а остальное время ждущий, пока прострекочет диск, и пользователь, с точки зрения которого все зависло.
Официальное решение - MGLRU, которое уже в официальном ядре. По факту оно тоже не работает. Из наиболее рабочего в настоящее время могу посоветовать prelockd, в который корне пресекает ситуацию, когда приходится выбрасывать «ненужный» код в надежде прочитать его повторно.
Исходная версия AEP, :
я в целом не понимаю почему при исчерпании ОЗУ Линукс делает лапки кверху
Все достаточно просто, если разобрать вопрос по частям. Во-первых надо понять, как Linux работает с кодом и данными, которые в исполняемых файлах и библиотеках. Во-вторых, разобраться, что такое out of memory в понимании ядра. В-третьих, склеить эти два куска новых знаний. Поехали.
В Linux есть два вида страниц памяти (переупрощаю): анонимная память и файловый кеш. Приложение может попросить кусок памяти и использовать на чтение и запись, как ему заблагорассудится - это анонимная память. А еще приложение может сказать «mmap», т.е. «дай мне фальшивый кусок памяти, а при попытках из него прочитать - давай мне данные вот из этого файла». При этом по факту ненужные куски файла не читаются. Ядро кеширует прочитанное в ОЗУ. За счет этого файлового кеша, пока он не сброшен, по производительности такая фальшивая память не отличается от обычной. Так вот, программы и библиотеки всегда грузятся через mmap.
Теперь разбираемся, что ядро делает, если памяти не хватает. Такое встречается сплошь и рядом, ведь ядро агрессивно кеширует прочитанные файлы. Так вот, первый шаг - это определение набора страниц памяти, которые можно просто выбросить без последствий. Как правило, это страницы файлового кеша, которые после чтения не были изменены. Их всегда можно прочитать заново, и никто ничего не заметит - если не следит за временем.
А теперь скомбинируем эти знания. Пользователь открывает кучу вкладок в браузере и грузит тяжелые сайты. Сайты ложатся в анонимную память, код браузера - в файловый кеш. В конечном итоге, когда пользователь застрял на pikabu и стал прокручивать вниз, памяти стало не хватать. Ядро нашло давно не использовавшуюся страницу файлового кеша - это часть кода браузера, отвечающая за переключение вкладок. Ядро его и выбросило, а освободившуюся память перепрофилировала под анонимную, чтобы там хранить очередной пост.
Затем пользователь таки переключает вкладку с pikabu на gmail. Ой, а код переключения вкладок из памяти выброшен! Надо вернуть его на место путем чтения с диска, пока никто не заметил… а вот некуда, так как свободных страниц нет. Ну, есть код отображения картинок, он большой и ненужный, давайте часть его выкинем, а код для переключения вкладок прочитаем. Переключили вкладку. Ой, а сейчас надо рисовать картинку, а код выброшен! Надо этот код загрузить, а что-то ненужное выбросить. Вот есть вторая половина распаковщика картинок, давайте выбросим ее, а первую половину прочитаем с диска. Ура, прочитали и выполнили… вот только опять приходится выполнять выброшенный код. Да ничего страшного, так и будем барахтаться по-собачьи, без паники, прогресс есть (!!!), убивать пользовательские процессы нет необходимости. Вот только получился процессор, работающий по факту на частоте 1 MHz, а остальное время ждущий, пока прострекочет диск, и пользователь, с точки зрения которого все зависло.
Официальное решение - MGLRU, которое уже в официальном ядре. По факту оно тоже не работает. Из наиболее рабочего в настоящее время могу посоветовать prelockd, в который корне пресекает ситуацию, когда приходится выбрасывать «ненужный» код в надежде прочитать его повторно.