9

Больше любопытства, чем проблемы; и, я признаю, кое-что из смущающего основного вопроса:

Я заметил, что во многих случаях на моей машине с Linux у меня будет ~ 500 МБ пространства подкачки, хотя у меня есть ~ 600 МБ неиспользуемой оперативной памяти.

Мое наивное понимание высокого уровня состояло в том, что пространство подкачки не срабатывает, пока не исчерпана память.

Я пошел дальше и сделал предположение, что эта ситуация должна быть связана с ядром Linux, потому что пользовательский процесс, который запрашивает память, делает это только логически и не имеет представления о том, поддерживается ли эта память физически ОЗУ или пространством подкачки.

Что приводит к вопросу, почему ядро превентивно использует пространство подкачки? Это часть алгоритма настройки производительности? Заменяет ли он дисковые части памяти, которые он считает наименее вероятными (например, схема LRU)? Если это так, не имеет ли смысл просто оставлять все в ОЗУ и только при приближении к истощению, тогда и только тогда переставлять части LRU из ОЗУ в пространство подкачки?

Я должен уточнить, мой сервер Linux имеет 2 ГБ оперативной памяти и 2 ГБ пространства подкачки.

4 ответа4

11

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

7

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

Например, допустим, вы хотите открыть большое изображение. Когда изображение загружено, требуется 300 МБ оперативной памяти. Если ядро использует всю оперативную память, которая может, для загрузки образа требуется, чтобы ядро перенесло 200 МБ из оперативной памяти на диск. Если он заранее опустошил оперативную память, вы сэкономите несколько миллисекунд.

7

2 причины:

  1. (@dtrosset) Linux заменит неиспользуемые биты программ, чтобы дать больше кеша и буферов.
  2. Возможно, вы использовали больше памяти в прошлом и поменяли некоторые вещи, и они не были заменены, потому что они не использовались, даже если то, что вытеснило их, теперь ушло.
1

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

Однако чрезмерная загрузка памяти и страх перед убийцей OOM не являются необходимыми частями опыта Linux. Просто установив для параметра sysctl vm/overcommit_memory значение 2, вы отключите поведение overcommit и навсегда остановите работу OOM killer. В большинстве современных систем должно быть достаточно дискового пространства, чтобы обеспечить достаточный файл подкачки для большинства ситуаций. Вместо того, чтобы не допустить уничтожения процессов домашних животных при исчерпании избыточной памяти, может быть проще всего избежать этой ситуации. [ Передышка от убийцы ООМ ]

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

Поскольку процессы представлены в своем собственном адресном пространстве или в "представлении" (именно так работает своп), у ядра есть много возможностей для управления этим. Используя пример разветвления также из статьи, ссылки на которую приведены выше, поскольку вероятность того, что страницы с общей памятью имеют гораздо больше шансов, чем свежее выделение большого объема неиспользуемой памяти, может быть выделена память для копирования при записи, что увеличивает количество операций подкачки. Когда он действительно записан (что может не произойти), тогда этот "совершенный обмен" может быть заменен любым неиспользуемым ОЗУ (что увеличивает использование ОЗУ и уменьшает использование свопинга). Представьте себе процесс с выделенным 500 МБ, который разветвляется на машине со всей или почти всей используемой оперативной памятью. Если в разделе подкачки доступно 500 МБ (а дисковое пространство дешевое, то насколько велик 1% современных дисков TB?:P), нет необходимости копировать память (пока, и, возможно, никогда), но ядро может гарантировать "успешно" и продолжайте использовать страницы общей памяти как можно дольше.

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

Хотя я не знаю точных деталей того, как работает менеджер памяти Linux, этот ответ - мое собственное обобщенное понимание и то, что я помню, читая за эти годы. Я попытался отредактировать этот ответ так, чтобы потребовалось минимальное понимание дизайна ОС (это значительно сложнее и не то, чем я сам ужасно интересуюсь), но, кажется, немного разболтано; пожалуйста, дайте мне знать, если вы видите, как это можно улучшить. С другой стороны, это не может быть таким смущающим основным вопросом.

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