9 ms·
> Unattended applications (like RDBMS or application container) should not allocate memory dynamically based on user input. This is incredibly easy to say, and
by lclarkmichalek 7y ago
> Unattended applications (like RDBMS or application container) should not allocate memory dynamically based on user input.
This is incredibly easy to say, and incredibly hard to do for any application of even moderate complexity. Getting people to accurately tune thread counts or concurrency limits is painful when working with diverse workloads, and getting a guaranteed upper bound on memory usage would be a lot harder. It's much more common to apply higher level techniques such as concurrency limits and load shedding to avoid OOMs and other resource starvation issues.
The other thing we can do is reduce the impact of OOMs, and accept that they exist as a tail event. There is software running on your system that doesn't have hard memory limits, and you will always have to consider OOMs and other similar failure cases when ensuring your system is resilient. As long as we can prevent those tail events becoming a correlated failure across our fleet, we can get a pretty reliable system.
- lmilcin 7y ago> This is incredibly easy to say, and incredibly hard to do for any application of even moderate complexity. I agree. But this is what it takes to build really reliable applications. For example, MISRA rules (C and C++ standards for automotive applications) forbid dynamic memory allocation completely after the application started. It also, if I remember well, forbids anything that could make it impossible to statically calculate stack requirements like recurrency. This is to make sure it is possible to calculate memory requirements statically.
- noselasd 7y agoSure, but not all applications can favorly be designed like that. It makes little sense for Excel to pre-allocate 4GB of memory to account for the user wanting to create a gigantic analysis in their spreadsheet over the next weeks, if all that the user wanted was to make a small sum of 100 narrow rows.
- deleted 7y ago[deleted]
- yason 7y agoThere is no problem for Excel to allocate memory dynamically for rows and columns as the user edits the sheet as long as it will also handle an allocation failure gracefully. That generally means the user input events call functions that fail and become no-ops until memory can be allocated again. That's how we used to write software until Linux ended up running everywhere, and that was the only way to write software for platforms without a MMU. As recently as a decade ago mobile phones, before Android, often had strict memory management. Each allocation could fail, and these failure paths had to be tested. Explicitly committing after a fork() would just make fork() cost a bit more but it would work. The fork() call would fail if there's no memory to duplicate all anonymous pages for the child process. But once it would succeed the child process would know it won't cause an OOM merely by writing into a memory location.
- Dylan16807 7y agoThat's fine if you actually want to fork, but it's pretty awful if your real goal is to immediately exec. What I would suggest in that case (with MMU) is a limit on how many pages the new process can dirty before it execs. Then you only need enough memory to provide that limit. And it shouldn't be too hard to statically prove that the limit is sufficient. (The parent process would be suspended in the meantime so it can't cause any pages to be duplicated.)
- yason 7y agoThe fork+exec is sort of a special, common case already. There have been attempts to explicitly implement that because even the current fork() has turned out to be too slow or too convoluted to implement, as witnessed by things like vfork() and posix_spawn(). We could just have fork() and fork_and_exec() sycalls separately. The other common case is to actually fork() a child process. Even then it would suffice to just reserve enough physical pages to make sure the child won't OOM-by-write, but only copy pages when they're actually being written to so you wouldn't be copying a gigabyte of memory even if you never used most of it. The kernel would allow applications to allocate at most physical mem size + swap size - any memory reserved for kernel. Thus you could still use MMU to push the least used pages into swap, and you could run more or larger programs that would fit in your RAM, but when memory is low these programs would always fail at the point of allocation, not memory access.
- AstralStorm 7y agoAnd this is not enough, because there are heuristic optimistic allocations and you will get OOM killed on pressure. On both Linux, Windows and FreeBSD. Probably also OS X. (The user is at fault but they do not know why.) vm.overcommit_memory should have never been a default... It's hard to change it back. On top of this is the potential for so-called swap death by thrashing.
- fulafel 7y agoInteresting. What counts as dynamic memory allocation in MISRA? Can you ship your own malloc serving memory from a global static char buffer? What about statically sized free lists? Or stdio functions (fopen/printf/etc) that use malloc internally?