malloc / calloc, очевидно, использует пространство подкачки для удовлетворения запроса, который превышает доступную свободную память.
Ну, нет.
Malloc / calloc использует виртуальную память.«Виртуальный» означает, что он не настоящий - это искусственно созданная иллюзия, созданная из подделки и лжи.Весь ваш процесс построен на этих искусственно созданных иллюзиях: поток - это виртуальный ЦП, сокет - это виртуальное сетевое соединение, язык C - это действительно спецификация для «абстрактной машины C», процесс - это виртуальный компьютер (реализующийабстрактная машина языков).
Ты не должен заглядывать за волшебный занавес.Вы не должны знать, что физическая память существует.Система не зависает - иллюзия только медленнее, но это прекрасно, потому что абстрактная машина C ничего не говорит о том, сколько времени должно быть, и не дает никаких гарантий производительности.
Что еще важнее;из-за иллюзии софт работает.Он не падает, потому что не хватает физической памяти.Отказ означает, что для успешного завершения программного обеспечения требуется бесконечное количество времени, и «бесконечное количество времени» на много порядков хуже, чем «медленнее из-за пространства подкачки».
Какзаставить malloc / calloc завершиться с ошибкой, если запрос превышает свободную физическую память (т. е. не использовать подкачку)
Если вы собираетесь заглянуть за волшебный занавес, вам нужно тщательно определить свои цели.
Например, представьте, что ваш процесс имеет 123 МБ кода и в настоящее время имеется 1000 МБ свободной физической ОЗУ;но (поскольку код находится в виртуальной памяти), только небольшая часть кода использует реальную память (а остальная часть кода находится на диске, потому что загрузчик ОС / исполняемый файл использовал файлы с отображенной памятью, чтобы не тратить реальную память до тех пор, пока она фактически не понадобится)).Вы решаете выделить 1000 МБ памяти (а поскольку операционная система, создающая иллюзию, не очень хороша, к сожалению, это приводит к выделению 1000 МБ реальной оперативной памяти).Затем вы выполняете еще немного кода, но код, который вы выполняете, еще не находится в реальной памяти, поэтому ОС должна извлечь код из файла на диске в физическое ОЗУ, но вы использовали все физическое ОЗУ, поэтому ОСнеобходимо отправить некоторые данные в пространство подкачки.
В другом примере представьте, что ваш процесс имеет 1 МБ кода и 1234 МБ данных, которые были аккуратно выделены, чтобы убедиться, что все вписывается в физическую память.Затем запускается совершенно другой процесс, и он выделяет 6789 МБ памяти для своего кода и данных;поэтому ОС отправляет все данные вашего процесса в пространство подкачки, чтобы удовлетворить другой процесс, который вы не можете контролировать.
РЕДАКТИРОВАТЬ
Проблема в том, чтоОС, обеспечивающая иллюзию, не очень хороша.Когда вы выделяете большой объем виртуальной памяти с помощью malloc()
или calloc()
;ОС должна иметь возможность использовать крошечный кусочек реальной памяти, чтобы лгать вам и избегать потребления большого объема реальной памяти.В частности (для большинства современных операционных систем, работающих на обычном оборудовании);ОС должна быть способна заполнить огромную область виртуальной памяти одной страницей, полной нулей, которая много раз отображается (по многим виртуальным адресам) как «только для чтения», так что выделение огромного объема виртуальной памяти почти не требует физическойОЗУ вообще (пока вы не запишете в виртуальную память, заставляя ОС выделять наименьшее количество физической памяти, необходимой для удовлетворения изменений).Конечно, если вы в конечном итоге сделаете запись во всю выделенную виртуальную память, то вы в конечном итоге исчерпаете физическую память и используете некоторое пространство подкачки;но это, вероятно, будет происходить постепенно, а не все сразу - многие крошечные задержки, разбросанные за большой промежуток времени, гораздо менее вероятны, чем одна огромная задержка.
Имея это в виду;Я хотел бы попробовать использовать mmap(..., MAP_ANONYMOUS, ...)
вместо (плохо реализовано) malloc()
или calloc()
.Это может означать, что вам приходится иметь дело с возможностью того, что выделенная виртуальная память не будет гарантированно инициализироваться нулями, но (в зависимости от того, для чего вы используете память) это, вероятно, будет легко обойти.