MAP_PRIVATE
для отображения требуется резервирование памяти, поскольку запись на эти страницы может привести к выделению при копировании при записи. Это означает, что вы не можете отобразить что-то слишком большое, чем ваш физический баран + своп. Попробуйте вместо этого использовать отображение MAP_SHARED
. Это означает, что запись в отображение будет отражена на диске - поэтому ядро знает, что оно всегда может освободить память, выполняя обратную запись, поэтому оно не будет ограничивать вас.
Я также отмечаю, что вы сопоставляете с PROT_WRITE
, но затем продолжаете и читаете из сопоставления памяти. Вы также открыли файл с O_RDONLY
- это само по себе может быть другой проблемой для вас; Вы должны указать O_RDWR
, если хотите использовать PROT_WRITE
с MAP_SHARED
.
Только для PROT_WRITE
это работает на x86, потому что x86 не поддерживает сопоставления только для записи, но может вызвать ошибки на других платформах. Запрос PROT_READ|PROT_WRITE
- или, если вам нужно только прочитать, PROT_READ
.
В моей системе (VPS с 676 МБ ОЗУ, 256 МБ подкачки) я воспроизвел вашу проблему; изменение на MAP_SHARED
приводит к ошибке EPERM
(поскольку я не могу записать в файл поддержки, открытый с O_RDONLY
). Изменение на PROT_READ
и MAP_SHARED
позволяет отображению быть успешным.
Если вам нужно изменить байты в файле, одним из вариантов будет сделать приватными только диапазоны файла, в который вы собираетесь записать. То есть munmap
и переназначить MAP_PRIVATE
областей, в которые вы собираетесь писать. Конечно, если вы намереваетесь записать в весь файл , вам потребуется 8 ГБ памяти для этого.
Альтернативно, вы можете написать 1
в /proc/sys/vm/overcommit_memory
. Это позволит выполнить запрос сопоставления; однако имейте в виду, что если вы на самом деле попытаетесь использовать все 8 ГБ памяти COW, ваша программа (или другая программа!) будет убита убийцей OOM.