В Linux, предполагая, что overcommit не отключен, вы можете использовать флаг MAP_NORESERVE
для mmap
, что гарантирует, что соответствующая страница не будет считаться выделенной памятью до доступа. Если overcommit полностью отключен, см. Ниже о страницах с несколькими сопоставлениями.
Обратите внимание, что в прошлом поведение Linux для нулевых страниц менялось; в некоторых версиях ядра простое чтение страницы приведет к ее выделению. С другими, запись необходима. Обратите внимание, что флаги защиты не вызывают выделение напрямую; однако они могут помешать вам случайно инициировать распределение. Поэтому для получения наиболее надежных результатов вам вообще следует избегать доступа к странице, набрав mprotect
с PROT_NONE
.
В качестве другого, более портативного варианта, вы можете сопоставить одну и ту же страницу в нескольких местах. То есть создайте и откройте пустой временный файл, отсоедините его, ftruncate
от некоторого разумного количества страниц, затем несколько раз mmap
со смещением 0 в файле. Это абсолютно гарантирует, что память будет считаться только один раз от использования памяти вашей программой. Вы даже можете использовать MAP_PRIVATE
для автоматического перераспределения при записи на страницу.
Однако это может потреблять больше памяти, чем метод MAP_NORESERVE
(как для данных отслеживания ядра, так и для страниц самого временного файла), поэтому я рекомендую вместо этого использовать MAP_NORESERVE
, когда он доступен. Если вы используете эту технику, попробуйте сделать область сопоставления достаточно большой (и укажите ее в /dev/shm
, если в Linux, чтобы избежать реального дискового ввода-вывода). Каждый отдельный mmap
вызов потребляет определенное количество (не поддающейся замене) памяти ядра для его отслеживания, поэтому хорошо бы уменьшить этот отсчет.