MAP_PRIVATE
mappings require a memory reservation, as writing to these pages may result in copy-on-write allocations. This means that you can't map something too much larger than your physical ram + swap. Try using a MAP_SHARED
mapping instead. This means that writes to the mapping will be reflected on disk - as such, the kernel knows it can always free up memory by doing writeback, so it won't limit you.
I also note that you're mapping with PROT_WRITE
, but you then go on and read from the memory mapping. You also opened the file with O_RDONLY
- this itself may be another problem for you; you must specify O_RDWR
if you want to use PROT_WRITE
with MAP_SHARED
.
As for PROT_WRITE
only, this happens to work on x86, because x86 doesn't support write-only mappings, but may cause segfaults on other platforms. Request PROT_READ|PROT_WRITE
- or, if you only need to read, PROT_READ
.
On my system (VPS with 676MB RAM, 256MB swap), I reproduced your problem; changing to MAP_SHARED
results in an EPERM
error (since I'm not allowed to write to the backing file opened with O_RDONLY
). Changing to PROT_READ
and MAP_SHARED
allows the mapping to succeed.
If you need to modify bytes in the file, one option would be to make private just the ranges of the file you're going to write to. That is, munmap
and remap with MAP_PRIVATE
the areas you intend to write to. Of course, if you intend to write to the entire file then you need 8GB of memory to do so.
Alternately, you can write 1
to /proc/sys/vm/overcommit_memory
. This will allow the mapping request to succeed; however, keep in mind that if you actually try to use the full 8GB of COW memory, your program (or some other program!) will be killed by the OOM killer.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…