6 ms·
What is the BSD answer to the OOM killer? Doesn't have one, right?
by angersock 12y ago
What is the BSD answer to the OOM killer? Doesn't have one, right?
- JoshTriplett 12y agoAs far as I know it doesn't. The Linux OOM killer came about based on the assumption that most processes, when faced with a NULL return from malloc, will unceremoniously exit. Thus, running out of memory would effectively randomly kill whatever process next attempted to make an allocation, and suddenly the system would have a bit more memory available. So rather than kill a random process, the OOM killer tries to kill a process actually responsible for using a huge amount of memory. Not always a sensible plan, and possibly not even something that should be on by default, but understandable.
- IgorPartola 12y agoThe OOM actually has three modes: 1. Rank processes by "badness" and kill the baddest one. This is not just based on memory usage, but is a fairly complicated and expensive algorithm. 2. Kill the process that caused the request that failed. 3. Do a kernel panic. This way if your server runs only a single process you care about, it'll just get rebooted, rather than killing the only process you actually want to keep running. Also, note that the article is talking about memory allocation inside the kernel, and not malloc() which is used in userland. It's one thing when your random Postgres process is out of RAM, it's quite another when the kernel is.
- jzwinck 12y ago1. This is the one where if you "less" a giant log file, your web server will get killed. Awesome. 2. This could be handled by returning NULL. 3. If your server only needs to run a single process, making that one process terminate would be much faster than rebooting the entire machine (commercial-grade servers can take ten minutes to POST).
- ogoffart 12y ago2. No. Because most allocations by the kernel are not a result of the program calling malloc. (They can be the result of a pagefault when the program tries to write on some memory)
- quotemstr 12y ago> They can be the result of a pagefault when the program tries to write on some memory How do you think malloc works? There's no malloc system call.
- voidlogic 12y ago>There's no malloc system call. Thats not really true. Not all dynamic allocation schemes rely on mmap, some use the brk and sbrk system calls. "In the original Unix system, brk and sbrk were the only ways in which applications could acquire additional data space; later versions allowed this to also be done using the mmap call." -https://en.wikipedia.org/wiki/Sbrk https://en.wikipedia.org/wiki/Sbrk Also mmap itself is also a system call, it usually just was called prior to the failing page allocation, not at the time of allocation failure.
- IgorPartola 12y agoThere are a couple of different things going on here: malloc() generally uses mmap() which is a syscall. It also can use brk()/sbrk(). Some implementations use both. There is also kmalloc() which is what's broken based on TFA. This is inside the kernel only and is not a syscall. So you are right, malloc() is not a syscall, but it may or may not use a syscall when you call it. You can, of course, write better code yourself: statically allocate the memory you need, then use malloc() on that big memory chunk. This way you are guaranteed not to cause the system any grief. Either your process starts, or it does not. After it starts, it is in complete control of its own memory.
- quotemstr 12y agoFirst of all, malloc implementations that rely on brk are simply broken. The whole idea of a process-wide data segment is broken and leads not only to awkwardness around thread safety safety, also the inability to decommit memory when it's no longer needed. Decent malloc implementations use mmap. Second, the whole idea that a page isn't really "allocated" until you touch it is just stupid, lazy, and terrible; it doesn't exist on sane operating systems like NT. On decent systems, mmap (or its equivalent) sets aside committed memory and malloc carves out pieces from that block. It's frustrating to see people who grew up with Linux not only understand how terrible and broken Linux's memory management is, but not realizing that it could be any other way.
- rcxdude 12y ago>1. Rank processes by "badness" and kill the baddest one. This is not just based on memory usage, but is a fairly complicated and expensive algorithm. AFAIK the algorithm has been simplified greatly: it's now just amount of memory weighted by the oom_score which can be set from userspace.
- nothrabannosir 12y agoBut what we need is a 4th option: a new SIGNOMEM that gives the process some time to release memory, or shut down cleanly if it can't.
- joosters 12y agoGood luck getting programs to process SIGNOMEM without allocating any more memory! Besides, if programs are using memory that could be discarded, it would be better if the kernel knew this in the first place and could therefore do the MM on their behalf.
- derefr 12y agoYou could have the system reserve a little tiny bit of extra memory (somewhat similar to the "disk space reserved for root" in ext2) that it would only ever hand out in response to malloc() attempts inside a SIGNOMEM handler. You're right, though; metadata on the allocations themselves marking them as release-on-memory-pressure would be much better.
- IgorPartola 12y agoNo it wouldn't. If a program has memory that it doesn't need and can live without it ought to just release it. Otherwise that is called a memory leak. I believe this was tried in early Android releases and was disastrous. Basically during an out of memory condition the kernel would ask every process "hey, can you release some memory?" And each process would reply with "nope, I need it all!" I don't see how the metadata is any different. What happens when the kernel yanks a page of memory from über a running process?
- gizmo686 12y agoPrograms often make time vs memory tradeoffs. In some cases, it is even possible for them to adjust these tradeoffs during runtime. The most common example is is file-system caches. Pretending (for the sake of argument) that the kernel did not automatically cache the file-system, a program may reasonably make this optimization [1]. In this case, the program can easily release some memory by clearing its cache. You could also be running a program with garbage collection that normally wouldn't bother doing a full sweep until it hit some memory usage threshold; again, it can do this on request. I'm sure that people can come up with other examples. [1] In fact, a program can request that the kernel not cache its file-system requests, in which case it would have actual reason to cache what it thinks it might need again.
- toast0 12y agoThe FreeBSD OOM killer finds the biggest process (swap + maybe resident), and kills it. But in my experience, you often get a good amount of allocation failures before the OOM killer gets triggered.
- angersock 12y agoCool. What does OpenBSD do?
- feld 12y agoI'm not certain that all the BSDs share a similar OOM killer approach. It would be interesting to see if they have diverged. edit: after some quick googling the OOM killer code on FreeBSD is certainly different than other BSDs because of changes needed to better cooperate with ZFS. Also, EMC has been working on code in this area too: https://wiki.freebsd.org/AvgPageoutAlgorithm https://wiki.freebsd.org/AvgPageoutAlgorithm Memory classes here are well described: https://wiki.freebsd.org/Memory https://wiki.freebsd.org/Memory Virtual memory system: https://www.freebsd.org/doc/en/books/arch-handbook/vm.html https://www.freebsd.org/doc/en/books/arch-handbook/vm.html Code: https://svnweb.freebsd.org/base/head/sys/vm/vm_pageout.c?view=markup https://svnweb.freebsd.org/base/head/sys/vm/vm_pageout.c?vie... Lots of good comments in there. /* * If we are critically low on one of RAM or swap and low on * the other, kill the largest process. However, we avoid * doing this on the first pass in order to give ourselves a * chance to flush out dirty vnode-backed pages and to allow * active pages to be moved to the inactive queue and reclaimed. */