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