4 ms·
> Why would you not want to be up-front about the fact that you don't have enough memory available to hand over to a process? Just because a process allocates
by wizeman 4y ago
> Why would you not want to be up-front about the fact that you don't have enough memory available to hand over to a process?
Just because a process allocates a certain amount of address space doesn't mean it will use all of it.
> The process requested a certain amount of memory to be allocated so surely it expects to use it, no?
No, not really. I think you are confusing memory usage with address space allocation.
You may wish to allocate a huge amount of address space for convenience purposes, as it could allow you to use much simpler data structures (such as sparse arrays) which can be a lot more performant than more complicated data structures and use a lot less memory (by orders of magnitude) than the address space that you allocated for them.
An example of this is AddressSanitizer's shadow memory, which is sort of a giant sparse bitmap whose address space is allocated up front, but only a small part of it is actually used at any one time.
From the blog post, it sounds like Windows has a separate system call that is required to be used in-between allocating address space and actually using it. I think this is a good design and I personally prefer it over Linux's overcommit design.
However, I think it has a disadvantage in that it could require you to do a lot more system calls (and therefore have slower performance) than would otherwise be needed in Linux, presumably (especially if the access patterns are unpredictable in advance?).
Also, if some process misbehaves and starts using more memory than there actually exists in the system, it can cause significant problems in other processes/applications that have nothing to do with it (as their allocations would start failing). Linux handles this by killing the misbehaving process, which allows the system to recover transparently / without intervention (at the risk of possibly killing innocent processes before actually killing the misbehaving one), hopefully allowing other processes to continue working as if nothing happened.
I think a reasonable approach could be to use Windows' system by default and guarantee that processes are never killed by the OS (which would benefit well-designed applications), but allow an application to optionally use overcommit if it wants the added performance (at the risk of being killed by the OOM killer if the system runs out of memory).
Unfortunately, I suspect that applications which actually handle out-of-memory conditions gracefully are very rare and that most of them would just crash or kill themselves if this happens, which on average is probably a worse outcome than letting the OS kill the misbehaving application.
- ziml77 4y agoI'm not convinced I like the overcommit, but it now makes more sense to me with your distinction of asking for address space versus using memory.
- dwattttt 4y ago> You may wish to allocate a huge amount of address space for convenience purposes, as it could allow you to use much simpler data structures (such as sparse arrays) which can be a lot more performant than more complicated data structures and use a lot less memory (by orders of magnitude) than the address space that you allocated for them. Windows does allow you to reserve address space without committing it, but it then requires you to commit the chunks before you use them (see VirtualAlloc + MEM_RESERVE)
- wizeman 4y ago> Windows does allow you to reserve address space without committing it, but it then requires you to commit the chunks before you use them (see VirtualAlloc + MEM_RESERVE) Personally, I think this is the right approach. Because you shouldn't have to decide between memory overcommit (which can fail badly in some reasonable scenarios) or "having to reserve all allocated address space of all processes in swap", which is way too pessimistic and would start causing unnecessary memory allocation failures in many reasonable scenarios. And I also think that even if you decide to support memory overcommit, it should be done per-process (at least), not at the whole system level like Linux is doing.
- magicalhippo 4y ago> Just because a process allocates a certain amount of address space doesn't mean it will use all of it. Indeed. > From the blog post, it sounds like Windows has a separate system call that is required to be used in-between allocating address space and actually using it. Precisely. You can reserve pages in the address space[1] without committing physical memory to back those pages. You can then later commit pages[2] when you want to use parts of that address space, or decommit[3] pages when you're done using them, without changing the reserved address space. Coming from a Windows background I much prefer this system. I understand why Linux, with its reliance on forking, has gone with the overcommit route, but I consider it a sub-par solution. At least for non-server systems. [1]: https://learn.microsoft.com/en-us/windows/win32/memory/virtual-memory-functions https://learn.microsoft.com/en-us/windows/win32/memory/virtu... [2]: https://learn.microsoft.com/en-us/windows/win32/api/memoryapi/nf-memoryapi-virtualalloc https://learn.microsoft.com/en-us/windows/win32/api/memoryap... [3]: https://learn.microsoft.com/en-us/windows/win32/api/memoryapi/nf-memoryapi-virtualfree https://learn.microsoft.com/en-us/windows/win32/api/memoryap...