Почему обсуждения «подмены» ведут себя так, будто информация может быть только в одном месте за раз? - PullRequest
4 голосов
/ 29 сентября 2008

Я читал о настраиваемой Linux подкачки, которая контролирует, насколько агрессивно ядро ​​подменяет память приложений на диск, когда они не используются. Если вы воспользуетесь термином Google, вы получите множество страниц, таких как this , в которых обсуждаются плюсы и минусы. В двух словах, аргумент звучит так:

Если ваша перестановка слишком мала, неактивные приложения будут забирать всю системную память, которую могут захотеть использовать другие программы.

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

Этот аргумент не имеет смысла для меня. Если у меня есть неактивное приложение, которое использует тонну памяти, почему ядро ​​не записывает свою память на диск И не оставляет другую копию этих данных в памяти? Кажется, это дает лучшее из обоих миров: если другому приложению нужна эта память, оно может немедленно запросить физическую ОЗУ и начать запись в нее, поскольку другая ее копия находится на диске и может быть заменена при пробуждении неактивного приложения вверх. И когда исходное приложение просыпается, любые его страницы, которые все еще находятся в оперативной памяти, могут использоваться как есть, без необходимости извлекать их с диска.

Или я что-то упустил?

Ответы [ 4 ]

3 голосов
/ 29 сентября 2008

Если у меня есть неактивное приложение, которое использует тонну памяти, почему ядро ​​не записывает свою память на диск И не оставляет другую копию этих данных в памяти?

Допустим, мы сделали это. Мы записали страницу на диск, но оставили ее в памяти. Некоторое время спустя другому процессу требуется память, поэтому мы хотим выкинуть страницу из первого процесса.

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

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

Если процесс выполняет запись на страницу, устранение ошибки на странице обходится еще дороже. Я бы предположил, что нетривиальное число этих страниц в конечном итоге пойдет на эту ошибку, что съедает выгоды, которые мы искали, оставив их в памяти.

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

(*) Все это очень похоже на механизм, называемый Copy-On-Write, который используется, когда процесс fork () s. Дочерний процесс, скорее всего, выполнит всего несколько инструкций и вызовет exec (), поэтому было бы глупо скопировать все родительские страницы. Вместо этого разрешение на запись забирают, а ребенку просто разрешают бежать. Копирование при записи - это выигрыш, потому что ошибка страницы почти никогда не устраняется: ребенок почти всегда сразу вызывает exec ().

1 голос
/ 29 сентября 2008

Даже если вы распишете память приложений на диск и сохраните ее в памяти, вам все равно придется решить, когда приложение следует считать «неактивным», и именно этим управляет swapiness. Пейджинг на диск стоит дорого с точки зрения ввода-вывода, и вы не хотите делать это слишком часто. В этом уравнении есть и другая переменная, и это тот факт, что Linux использует оставшуюся память в качестве дискового буфера / кэша.

0 голосов
/ 29 июля 2009

Первым делом виртуальная машина очищает страницы и перемещает их в чистый список.
При очистке анонимной памяти (вещи, которые не имеют реального хранилища файлов, вы можете увидеть сегменты в / proc // maps, которые являются анонимными и не имеют хранилища vnode файловой системы), первое, что собирается сделать виртуальная машина, это возьмите «грязные» страницы и «очистите», а затем записав содержимое страницы для замены. Теперь, когда виртуальная машина испытывает нехватку полностью свободной памяти и обеспокоена своей способностью предоставлять новые свободные страницы для использования, она может просматривать список «чистых» страниц и основываясь на том, как недавно они использовались и какой тип памяти они переместят эти страницы в свободный список.

Как только страницы памяти помещены в свободный список, они больше не связаны с содержимым, которое они имели ранее. Если программа приходит по ссылке на область памяти, которую страница обслуживала ранее, то в программе произойдет серьезная ошибка, и (скорее всего, совершенно другая) страница будет извлечена из списка свободных данных, и данные будут считаны на страницу с диска. Как только это будет сделано, страница на самом деле все еще будет «чистой», поскольку она не была изменена. Если виртуальная машина решит использовать эту страницу при обмене для другой страницы в ОЗУ, то страница будет снова «загрязнена», или если приложение записало на эту страницу, оно будет «загрязнено». И тогда процесс начинается снова.

Кроме того, замена серверов довольно ужасна для серверных приложений в среде, чувствительной к бизнесу / транзакциям / онлайн / задержке. Когда у меня есть 16 ГБ ОЗУ, где я не использую много браузеров и графических интерфейсов, я обычно хочу, чтобы все мои приложения были почти закреплены в памяти. Большая часть моей оперативной памяти, как правило, составляет 8-10 ГБ кучи Java, которую я НИКОГДА не хочу выгружать на диск, когда-либо, и доступными являются такие процессы, как mingetty (но даже там страницы glibc в этих приложениях используется другими приложениями и фактически используется, поэтому даже размер RSS этих бесполезных процессов в основном используется совместно используемыми страницами). Обычно я не вижу более 10 МБ из 16 ГБ, очищенных для замены. Я бы посоветовал очень, очень низкие показатели перестановки или нулевую перестановку для серверов - неиспользуемые страницы должны составлять небольшую долю от общего объема ОЗУ, и попытка восстановить, что относительно небольшой объем ОЗУ для буферного кеша может привести к перестановке страниц приложения и возникновению задержек в обращении. запущенное приложение.

0 голосов
/ 04 февраля 2009

Согласно этому 1 это именно то, что делает Linux.

Я все еще пытаюсь разобраться во всем этом, поэтому любые авторитетные ссылки приветствуются.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...