# Virtual Memory Overcommit _2026 August_ There's a distinction between reserving virtual memory and having it "committed" by the kernel. This isn't the same thing as it being backed by physical memory. One could think of the state of vmem as having three levels: 1. Reserved 2. Committed 3. Physically backed Also, the physical backing could be RAM or SWAP, but that's not important for our case. What matters is that reserving is always "free" because it's just a reservation within the virtual address space of the process itself, whereas committing *may* be checked against the available RAM/SWAP of the whole system, and possibly denied even before it needs physical backing. There may also be explicit commit limits unrelated to RAM/SWAP availability. Committing memory despite the system potentially not having enough RAM/SWAP is called overcommit. ## When is overcommit allowed According to some quick research (don't cite this) the breakdown of which kernels allow overcommit is as follows: * MacOS: Always allowed. * Linux, FreeBSD, NetBSD: Allowed by default; configurable. * OpenBSD, MS Windows: Not allowed. So, for Zisp to cover even just all POSIX systems, it will need some way to reserve without committing. ## How to reserve without commit Under POSIX, you reserve without committing by calling `mmap()` with `PROT_NONE` for the protection argument. Of course, the behavior is not actually documented as part of POSIX, but I suppose it should be safe to assume that any sane implementation would not count memory that's inaccessible towards any kind of commit limit. Surprisingly, even the Linux documentation doesn't *explicitly* guarantee that a `PROT_NONE` mapping is "free" but I think it's safe to assume given there's projects in the wild like jemalloc and the JVM that already use this trick, so Linux wouldn't dare change the behavior. There's also `MAP_NORESERVE` under Linux, which can achieve the same effect, but I guess it's less portable. Funnily, there's even some old discussions about the kernel not honoring `MAP_NORESERVE` under strict overcommit policies, while `PROT_NONE` works. Oh and also, "NORESERVE" flies in the face of the terminology I use here, and there's also comments on LWN about how it's a misnomer: [https://lwn.net/Articles/627557/](https://lwn.net/Articles/627557/) Anyhow, TL;DR: Use `PROT_NONE` on POSIX; it should hopefully work as desired on any common POSIX system besides OpenBSD. On MS Windows, you reserve by calling `VirtualAlloc()` with the `MEM_RESERVE` flag, and commit with the `MEM_COMMIT` flag. ## Committing as you go When you've reserved without commit, you then actually need to tell the kernel when you need the memory committed. On POSIX, you can't use it under `PROT_NONE` anyway (the whole point) and asking the system to commit it is a matter of calling `mprotect()` to set the protection mode to `PROT_READ | PROT_WRITE` instead. Likewise, on MS Windows, trying to access in any way a region of vmem not yet committed is an error; you need to call `VirtualAlloc` again, on a sub-range of the full range, with `MEM_COMMIT` this time. ## Disadvantages Syscalls are costly! Would be great if we only ever needed a single one at startup, but alas. Thankfully, after my latest tweaks to Meta Alloc, it already bumps watermarks in chunks of at least 64 KiB. That's a perfect spot for inserting the `mprotect()` or `VirtualAlloc()` calls. I may just do that unconditionally, at least for now, because it's easy to make it configurable if ever needed.