Top
Best
New

Posted by signa11 7 days ago

Vm.overcommit_memory=2 is the right setting for servers(ariadne.space)
109 points | 143 commentspage 3
renehsz 7 days ago|
Strongly agree with this article. It highlights really well why overcommit is so harmful.

Memory overcommit means that once you run out of physical memory, the OOM killer will forcefully terminate your processes with no way to handle the error. This is fundamentally incompatible with the goal of writing robust and stable software which should handle out-of-memory situations gracefully.

But it feels like a lost cause these days...

So much software breaks once you turn off overcommit, even in situations where you're nowhere close to running out of physical memory.

What's not helping the situation is the fact that the kernel has no good page allocation API that differentiates between reserving and committing memory. Large virtual memory buffers that aren't fully committed can be very useful in certain situations. But it should be something a program has to ask for, not the default behavior.

charcircuit 4 days ago||
>terminate your processes with no way to handle the error. This is fundamentally incompatible with the goal of writing robust and stable software

Having an assumption that your process will never crash is not safe. There will always be freak things like CPUs taking the wrong branch or bits randomly flipping. Parting of design a robust system is being tolerant to things like this.

Another point also mentioned is this thread is that by the time you run out of memory the system already is going to be in a bad state and now you probably don't have enough memory to even get out of it. Memory should have been freed already by telling programs to lighten up on their memory usage or by killing them and reclaiming the resources.

PunchyHamster 4 days ago|||
It's not harmful. It's necessary for modern systems that are not "an ECU in a car"

> Memory overcommit means that once you run out of physical memory, the OOM killer will forcefully terminate your processes with no way to handle the error. This is fundamentally incompatible with the goal of writing robust and stable software which should handle out-of-memory situations gracefully.

The big software is not written that way. In fact, writing software that way means you will have to sacrifice performance, memory usage, or both because you either * need to allocate exactly what you always need and free it when it gets smaller (if you want to keep memory footprint similar)m and that will add latency * over-allocate, and waste RAM

And you'd end up with MORE memory related issues, not less. Writing app where every allocation can fail is just nightmarish waste of time for 99% of the apps that are not "onboard computer of a space ship/plane"

201984 4 days ago|||
> What's not helping the situation is the fact that the kernel has no good page allocation API that differentiates between reserving and committing memory.

mmap with PROT_NONE is such a reservation and doesn't count towards the commit limit. A later mmap with MAP_FIXED and PROT_READ | PROT_WRITE can commit parts of the reserved region, and mmap calls with PROT_NONE and MAP_FIXED will decommit.

barchar 4 days ago|||
Even besides the aforementioned fork problems not having overcommit doesn't mean you can handle oom correctly by just handling errors from malloc!
hparadiz 4 days ago||
That's a normal failure state that happens occasionally. Out of memory errors come up all the time when writing robust async job queues. There are a lot of other reasons a failure could happen but running out of memory is just one of them. Sure I can force the system to use swap but that would degrade performance for everything else so it's better to let it die and log the result and check your dead letter queue after.
jcalvinowens 4 days ago||
There's a reason nobody does this: RAM is expensive. Disabling overcommit on your typical server workload will waste a great deal of it. TFA completely ignores this.

This is one of those classic money vs idealism things. In my experience, the money always wins this particular argument: nobody is going to buy more RAM for you so you can do this.

toast0 4 days ago||
Even if you disable overcommit, I don't think you will get pages assigned when you allocate. If your allocations don't trigger an allocation failure, you should get the same behavior with respect to disk cache using otherwise unused pages.

The difference is that you'll fail allocations, where there's a reasonable interface for errors, rather than failing at demand paging when writing to previously unused pages where there's not a good interface.

Of course, there are many software patterns where excessive allocations are made without any intent of touching most of the pages; that's fine with overcommit, but it will lead to allocation failures when you disable overcommit.

Disabling overcommit does make fork in a large process tricky; I don't think the rant about redis in the article is totally on target; fork to persist is a pretty good solution, copy on write is a reasonable cost to pay while dumping the data to disk and then it returns to normal when the dump is done. But without overcommit, it doubles the memory commitment while the dump is running, and that's likely to cause issues if redis is large relative to memory and that's worth checking for and warning about. The linked jemalloc issue seems like it could be problematic too, but I only skimmed; seems like that's worth warning about as well.

For the fork path, it might be nice if you could request overcommit in certain circumstances... fork but only commit X% rather than the whole memory space.

jcalvinowens 4 days ago|||
You're correct it doesn't prefault the mappings, but that's irrelevant: it accounts them as allocated, and a later allocation which goes over the limit will immediately fail.

Remember, the limit is artificial and defined by the user with overcommit=2, by overcommit_ratio and user_reserve_kbytes. Using overcommit=2 necessarily wastes RAM (renders a larger portion of it unusable).

toast0 4 days ago|||
> Using overcommit=2 necessarily wastes RAM (renders a larger portion of it unusable).

The RAM is not unusable, it will be used. Some portion of ram may be unallocatable, but that doesn't mean it's wasted.

There's a tradeoff. With overcommit disabled, you will get allocation failure rather than OOM killer. But you'll likely get allocation failures at memory pressure below that needed to trigger the OOM killer. And if you're running a wide variety of software, you'll run into problems because overcommit is the mainstream default for Linux, so many things are only widely tested with it enabled.

jcalvinowens 4 days ago|||
> The RAM is not unusable, it will be used. Some portion of ram may be unallocatable

I think that's a meaningless distinction: if userspace can't allocate it, it is functionally wasted.

I completely agree with your second paragraph, but again, some portion of RAM obtainable with overcommit=0 will be unobtainable with overcommit=2.

Maybe a better way to say it is that a system with overcommit=2 will fail at a lower memory pressure than one with overcommit=0. Additional RAM would have to be added to the former system to successfully run the same workload. That RAM is waste.

PunchyHamster 4 days ago|||
it's absolutely wasted if apps on server don't use disk (disk cache is pretty much only thing that can use that reserved memory).

You can have simple web server that took less than 100MB of RAM take gigabytes, just because it spawned few COW-ed threads

loeg 4 days ago|||
If the overcommit ratio is 1, there is no portion rendered unusable? This seems to contradict your "necessarily" wastes RAM claim?
jcalvinowens 4 days ago||
Read the comment again, that wasn't the only one I mentioned.
loeg 4 days ago||
Please point out what you're talking about, because the comment is short and I read it fully multiple times now.
PunchyHamster 4 days ago|||
> Even if you disable overcommit, I don't think you will get pages assigned when you allocate. If your allocations don't trigger an allocation failure, you should get the same behavior with respect to disk cache using otherwise unused pages.

Doesn't really change the point. The RAM might not be completely wasted, but given that near every app will over-allocate and just use the pooled memory, you will waste memory that could otherwise be used to run more stuff.

And it can be quite significant, like it's pretty common for server apps to start a big process and then have COWed thread per connection in a pool, so your apache2 eating maybe 60MB per thread in pool is now in gigabytes range at very small pool sizes.

Blog is essentially call to "let's make apps like we did in the DOS era" which is ridiculus

wmf 4 days ago|||
If you have enough swap there's no waste.
jcalvinowens 4 days ago||
Wasted swap is still waste, and the swapping costs cycles.
wmf 4 days ago||
With overcommit off the swap isn't used; it's only necessary for accounting purposes. I agree that it's a waste of disk space.
loeg 4 days ago||
How does disabling overcommit waste RAM?
jcalvinowens 4 days ago|||
Because userspace rarely actually faults in all the pages it allocates.
loeg 4 days ago||
Surely the source of the waste here is the userspace program not using the memory it allocated, rather than whether or not the kernel overcommits memory. Attributing this to overcommit behavior is invalid.
PunchyHamster 4 days ago|||
The waste comes with asterisk

That "waste" (that overcommit turns into "not a waste") means you can do far less allocations, with overcommit you can just allocate a bunch of memory and use it gradually, instead of having to do malloc() every time you need a bit of memory and free() every time you get rid of it.

You'd also increase memory fragmentation that way possibly hitting performance.

It's also pretty much required for GCed languages to work sensibly

jcalvinowens 4 days ago||||
Obviously. But all programs do that and have done it forever, it's literally the very reason overcommit exists.
userbinator 4 days ago||
Only the poorly-written ones, which are unfortunately the majority of them.
nickelpro 4 days ago|||
Reading COW memory doesn't cause a fault. It doesn't mean unused literally.

And even if it's not COW, there's nothing wrong or inefficient about opportunistically allocating pages ahead of time to avoid syscall latency. Or mmapping files and deciding halfway through you don't need the whole thing.

There are plenty of reasons overcommit is the default.

PunchyHamster 4 days ago|||
overcommit 0

- Apache2 runs. - Apache2 takes 50MB. - Apache2 spawns 32 threads. - Apache2 takes 50MB + (per-thread vars * 32)

overcommit 2

- Apache2 runs. - Apache2 takes 50MB. - Apache2 spawns 32 threads. - Apache2 takes 50MB + (5032) + (per-thread vars 32)

Boom, Now your simple apache server serving some static files can't fit on 512MB VM and needs in excess of 1.7GB of memory just to allocate

PunchyHamster 4 days ago||
Sure if you don't like your stuff to work well. 0 is default for a reason, and "my specific workload is buggy with 0" is not a problem with it, just the reason there are other options

Advertising for 2 with "but apps should handle it" is utter ignorance, and redis example shows that, the database is using the COW fork feature for basically the reason it exists, as do many, many servers and the warning is pretty much tailored for people thinking they are clever and not understanding memory subsystem

sevensor 3 days ago|
I was just looking at an OOM situation this week. I disagree that turning overcommit off helps specifically with locality. Finding the straw that breaks the camel’s back doesn’t necessarily help you fix the problem. If you don’t understand the whole system, it’s going to be hard to debug regardless.