News for hackers. Stuff that matters.
Re:Linux Memory Overcommit (2007) by pcwalton on Sunday August 18, 2024 @05:50PM (#41285817)
Reminder: if overcommit as a concept seems distasteful, the real ire should be directed at the Unix fork syscall, an API that will always fail on a process using over 50% of the available memory without overcommit. Ideally apps would use vfork or posix_spawn instead, but that isn't the world we live in. Overcommit is a sensible way to help apps that use a lot of memory "just work". You can always turn it off if you don't need apps using a lot of memory to be able to fork.
Re:Linux Memory Overcommit (2007) by userbinator on Sunday August 18, 2024 @08:15PM (#41286640)
That explains why Windows, which has a process model based on spawning and not forking, never had overcommit.
Re:Linux Memory Overcommit (2007) by ynik on Monday August 19, 2024 @05:40AM (#41289427)
However Windows has stacks that commit on-demand, which is kinda similar to overcommit. It can result in programs terminating on any random function call (if that call requires allocating a new page of stack). https://learn.microsoft.com/en-us/windows/win32/procthread/t...

However this is very rare to happen in practice -- stack growth isn't very frequent in typical applications; so usually a malloc() will fail first in low-memory situations.

A Windows program can avoid the risk of getting terminated on stack growth by specifying equal commit and reserve sizes for the stack. So in least in theory, it's possible to write a windows program that is reliable in low memory situations.

Re:Linux Memory Overcommit (2007) by senderista on Sunday August 18, 2024 @06:10PM (#41285944)
There are also legitimate uses of overcommit for reserving huge areas of virtual memory and relying on demand paging to allocate physical memory, although strictly speaking enabling overcommit isn’t necessary if you separate the “reserve” (mmap(PROT_NONE)) and “commit” (mmap(MAP_FIXED, PROT_READ | PROT_WRITE)) stages (which is what Windows forces you to do).
Re:Linux Memory Overcommit (2007) by dap on Sunday August 18, 2024 @06:12PM (#41285959)
I’m not sure how this works on Linux exactly but in principle you don’t need to support overcommit to avoid that problem. On illumos for example anonymous memory allocations come from swap, which is a virtual resource that includes both disk and memory. You do still have this problem if something is using more than half of swap, but (1) that’s much larger, and (2) you can augment it with more disk space, which won’t actually be used unless stuff actually uses all the physical memory. This has its own tradeoffs but it’s useful to keep in mind that there are other ways to do things.
Re:Linux Memory Overcommit (2007) by wmf on Sunday August 18, 2024 @06:58PM (#41286233)
If available memory means physical + swap then you're saying the same thing as pcwalton.
Re:Linux Memory Overcommit (2007) by pcwalton on Monday August 19, 2024 @01:40AM (#41288115)
Right, available memory includes swap. (That's why I didn't say "available RAM".)
Re:Linux Memory Overcommit (2007) by thanatos519 on Sunday August 18, 2024 @06:23PM (#41286026)
I thought fork was copy on write nowadays.
Re:Linux Memory Overcommit (2007) by wmf on Sunday August 18, 2024 @06:57PM (#41286227)
Fork is copy-on-write. The problem is that there's no way for fork() to know how much memory the child process needs. It might call exec() immediately, using very little memory. It might keep running, mostly sharing pages with the parent. It might touch every memory page, requiring a lot of memory.
Re:Linux Memory Overcommit (2007) by layer8 on Sunday August 18, 2024 @06:56PM (#41286223)
It is, but “write” doesn’t have an error code it can return on out-of-memory.

The whole crux of overcommit is that the affected process doesn’t get a chance to gracefully fall back or shutdown on OOM conditions at defined places in the code (like at invocations of malloc).

Re:Linux Memory Overcommit (2007) by jabl on Monday August 19, 2024 @01:55AM (#41288194)
This article explains the problems with fork pretty well: https://www.microsoft.com/en-us/research/uploads/prod/2019/0...
Re:Linux Memory Overcommit (2007) by rcxdude on Monday August 19, 2024 @03:22AM (#41288616)
Also I would suggest using a Windows machine which seems to run out of memory despite hundreds of gigabytes of swap and yet still ~70% of RAM full. I don't know what's causing the bug but it affects multiple systems I use and it's a right nuisance with a nearly full disk to have >10% of it sitting there idle just in case whatever's over-allocating memory decides to actually use it (I mean, I guess I could also direct my ire at whatever broken accounting fails to actually tell me what's causing it as well, but I can be mad at two things at once).
Re:Linux Memory Overcommit (2007) by shoo on Monday August 19, 2024 @06:12AM (#41289609)
yup. i recall first being exposed to this while trying to understand why a memory-hog backend service was being oom-killed in production while attempting to spawn a resource-light subprocess via fork+exec, while there was still a good portion of free memory to use.

the more you read about linux oom killer, overcommit, linux memory accounting heuristics, copy-on-write, fork+exec as a mechanism to spawn an unrelated process, the more surprising it is that anything works at all even some of the time.

Re:Linux Memory Overcommit (2007) by __turbobrew__ on Sunday August 18, 2024 @06:06PM (#41285918)
If you want to optimize for throughout one option is to overcommit resources (CPU/MEM/IO/NET) but utilize backpressure mechanisms to reduce load during times of saturation.

Kubernetes does this through node pressure eviction but it is pretty easy to hook into the pressure stall information and have the application handle this as well (for example, start returning 429 HTTP responses when PSI goes over a certain level).

At the end of the day the optimal overcommit is workload dependent — good metrics and an iterative approach is needed.

Re:Linux Memory Overcommit (2007) by eru on Monday August 19, 2024 @02:39AM (#41288417)
You probably also want to do somewhat intelligent load shedding, where you basically make sure you drop the most expendable items first.

That's a basic fact of life for CPU cycles even for consumers on their machines, we call that just CPU priorities or so. But it's also useful for the other resources; but there it's a bit more disruptive, because we generally need to disrupt a program to eg claim back the disk space it uses.

Re:Linux Memory Overcommit (2007) by johnea on Sunday August 18, 2024 @06:21PM (#41286020)
Is any of this still applicable in 2024?

One has to doubt...

Re:Linux Memory Overcommit (2007) by graymatters on Sunday August 18, 2024 @09:08PM (#41286939)
Doubt - based on what?
Re:Linux Memory Overcommit (2007) by worthless-trash on Sunday August 18, 2024 @10:54PM (#41287392)
Knowledge, GP probably thinks that the kernel world moves like the userspace (probably js) world.

Which clearly isnt true. If OS development worked like userspace/web dev we'd all be in much more pain.

Re:Linux Memory Overcommit (2007) by nabla9 on Sunday August 18, 2024 @06:39PM (#41286128)
As then as now, you can manage it.

vm.overcommit_memory == 0 heuristic overcommit

vm.overcommit_memory == 1 (full overcommit) allows allocating more memory than there is ram + swap.

vm.overcommit_memory == 2 never overcommit. There must be enough physical ram or virtual swap to allocate the memory.

Re:Linux Memory Overcommit (2007) by layer8 on Sunday August 18, 2024 @06:54PM (#41286210)
Can this be set for a specific process (or process group/tree), or only globally?
Re:Linux Memory Overcommit (2007) by nabla9 on Sunday August 18, 2024 @07:13PM (#41286310)
Globally

For a process you can use setrlimit() (ulimit command)

Re:Linux Memory Overcommit (2007) by silon42 on Monday August 19, 2024 @04:57AM (#41289201)
I'd want the OOM killer to kill processes with more over-commit first.
Re:Linux Memory Overcommit (2007) by jart on Monday August 19, 2024 @05:33AM (#41289389)
Why? There are many innocent applications that consume lots of virtual memory with no intention of using it. Sometimes sparse algorithms call for that sort of thing. It can be a nice crutch when you're in a pinch for time. A good example of a tool that does this is TSAN. It gobbles up virtual address space, which is practically free, thanks to the magic of modern MMUs. That's too powerful and good a thing to need to give up completely.
Re:Linux Memory Overcommit (2007) by kaba0 on Monday August 19, 2024 @06:08AM (#41289579)
Another example would be the JVM’s new low-latency GC, ZGC, that does some smart addressing tricks to store some information in pointer addresses themselves, effectively tripling the actual memory usage when naively looked at through virt memory.
Re:Linux Memory Overcommit (2007) by layer8 on Monday August 19, 2024 @07:31AM (#41290086)
Such applications could handle this explicitly, e.g. with mmap and mprotect. In principle there is no reason for such use-cases to rely on implicit overcommit behavior. Which also isn't present on Windows.
Re:Linux Memory Overcommit (2007) by jart on Monday August 19, 2024 @08:16AM (#41290369)
That's because Windows forces you to use special userspace libraries that account for memory and let you create "reservations" for large regions, without actually populating entries in the MMU (i.e. PML4t). Linux doesn't have that. You create reservations for large memory regions by allocating virtual memory, which of course doesn't become real (resident) until you use it. That's overcommit. But since there's no userspace libraries like WIN32 forced upon you on Linux, there's really no way for the kernel to know your intent when it comes to memory, because the abstractions for memory on Linux are so simple. Windows has a ridiculous byzantine system, which some people think is better. But people are really missing the point when they try to make an apples-to-apples comparison between the two systems of memory management. It's not a question of (a) overcommit good, vs. (b) overcommit bad. Anyone who thinks either is a fool. Linux is simply a system that requires a smart system administrator who understands your use cases and can tune sysctl accordingly when you want to push beyond the normal boundaries.
Re:Linux Memory Overcommit (2007) by layer8 on Monday August 19, 2024 @08:43AM (#41290551)
It seems to me that the prot parameter and/or MAP_NORESERVE would indicate the intent.
Re:Linux Memory Overcommit (2007) by kaba0 on Monday August 19, 2024 @07:54AM (#41290221)
It might actually be using that, I’m not intimately familiar with the topic.
Re:Linux Memory Overcommit (2007) by layer8 on Monday August 19, 2024 @07:57AM (#41290235)
Yes, I would expect that as well.

Implicit overcommit is really only necessary for fork and general backwards compatibility.

Re:Linux Memory Overcommit (2007) by ackfoobar on Friday August 23, 2024 @02:34PM (#41331708)
BTW the newer Generational ZGC is not using multi-mapped memory any more.
Re:Linux Memory Overcommit (2007) by kevingadd on Sunday August 18, 2024 @07:21PM (#41286368)
I like to run my development VM with overcommit_memory == 2, but I recently learned that the way it actually fails is pretty confusing. It's not an orderly 'abort: malloc failed' or process termination like I would've expected. Instead, you get weird intermittent failures that don't look like OOMs and your system appears to have plenty of free memory at the time.

Still good for flushing out scenarios where i.e. your build process needs 64GB of memory for approximately 500ms and then drops back down to reasonable levels, due to parallelism

Re:Linux Memory Overcommit (2007) by dataflow on Sunday August 18, 2024 @09:30PM (#41287028)
That sounds wild. How else can it possibly fail than by failing malloc? Where do the intermittent failures occur, if not in the return value? Could it be some part of your code isn't checking the return value for NULL?
Re:Linux Memory Overcommit (2007) by usefulcat on Sunday August 18, 2024 @10:51PM (#41287376)
IIUC, the way overcommit works on Linux is the memory returned by malloc() is not actually mapped to physical memory until it is accessed. So malloc may succeed and then at some point later you may get a segfault or similar when something actually tries to access that memory.
Re:Linux Memory Overcommit (2007) by dataflow on Sunday August 18, 2024 @11:05PM (#41287438)
> IIUC, the way overcommit works on Linux

Doesn't vm.overcommit_memory == 2 disable overcommit? That's the situation we're talking about...

Re:Linux Memory Overcommit (2007) by usefulcat on Sunday August 18, 2024 @11:22PM (#41287523)
You're correct; for some reason I didn't interpret the question in that context. I was thinking about when vm.overcommit_memmory is 0 or 1.
Re:Linux Memory Overcommit (2007) by cyberax on Sunday August 18, 2024 @11:04PM (#41287433)
malloc() will not return unmapped memory for small allocations. Your process might get killed if malloc() fails to get more backing pages.
Re:Linux Memory Overcommit (2007) by dent9876543 on Monday August 19, 2024 @07:02AM (#41289878)
Do you mean that my process might get killed [by the OOM killer] if /another process/ fails to get more backing pages?

Or are you suggesting that there is some other failure path that results in my process getting killed if my own malloc() fails to get pages? (That seems wrong. Should simply return NULL in that case, no?)

Re:Linux Memory Overcommit (2007) by cyberax on Monday August 19, 2024 @12:15PM (#41292299)
> Do you mean that my process might get killed [by the OOM killer] if /another process/ fails to get more backing pages?

It can be your process or some other process, depending on the OOM killer weights and heuristics.

> Or are you suggesting that there is some other failure path that results in my process getting killed if my own malloc() fails to get pages? (That seems wrong. Should simply return NULL in that case, no?)

No, malloc() in Linux will never return NULL for small allocations. What happens is that glibc will try to get more pages for its heap by calling mmap(). The call to mmap() will result in the OOM killer waking up and freeing some memory.

It then can kill some other process, and your process mmap() will succeed, or it can kill your process, and in this case mmap() never returns.

Re:Linux Memory Overcommit (2007) by cyberax on Sunday August 18, 2024 @11:03PM (#41287428)
> That sounds wild. How else can it possibly fail than by failing malloc?

By killing your process and/or by failing fork()s.

In general, malloc() in Linux will never fail for small allocations.

Re:Linux Memory Overcommit (2007) by fulafel on Monday August 19, 2024 @03:20AM (#41288602)
With overcommit disabled, fork may fail, but your other claims are backwards: malloc can fail, and processes aren't killed.
Re:Linux Memory Overcommit (2007) by cyberax on Monday August 19, 2024 @12:23PM (#41292374)
I suggest trying that :) You'd be surprised.

glibc allocator, like pretty much any other allocator, maps pages in advance without touching them. It's quite likely that you'll get OOM killed when you first try to touch them, rather than during mmap() for new pages.

Re:Linux Memory Overcommit (2007) by fulafel on Monday August 19, 2024 @10:39PM (#41296271)
Assuming you've also set overcommit_ratio to a conservative value, this would mean that the kernel overcommit=2 setting is not working, since mmap-ing writable pages counts as allocation from overcommit POV. It's a kernel sysctl, so I wouldn't expect it to change glibc's behaviour. There don't seem to be any open bugs about this in the kernel bugzilla. But do tell if you have found a bug in this area.

(This is documented in https://www.kernel.org/doc/html/latest/mm/overcommit-account... )

Re:Linux Memory Overcommit (2007) by ploxiln on Monday August 19, 2024 @04:58AM (#41289207)
> malloc() in Linux will never fail for small allocations

That's in kernel-space, not user-space processes. If you have overcommit disabled, it will be user-space processes making syscalls mmap() or sbrk() to get more heap memory (in which small allocations reside), that fails with an error return code, I assume. But I guess it could also fail to auto-grow the main thread stack, and presumably get a segfault. If the kernel needs to allocate more memory for a fork(), that syscall can fail. But if the kernel needs to allocate memory for some other internal purpose, probably back to the OOM killer, I guess ... hopefully this would be very rare?

Re:Linux Memory Overcommit (2007) by cyberax on Monday August 19, 2024 @12:21PM (#41292353)
> If you have overcommit disabled, it will be user-space processes making syscalls mmap() or sbrk() to get more heap memory (in which small allocations reside), that fails with an error return code, I assume.

Nope. No overcommit simply means that the OOM killer will be invoked earlier. The errors likely won't happen on the synchronous path due to the way glibc() maps the pages.

Long ago, I tried to write an OOM-resilient container library, and I wanted to test it. It worked as expected on Windows, but on Linux I was not able to get NULLs from malloc(). No amount of MLOCKALL and other tricks helped.

Re:Linux Memory Overcommit (2007) by ploxiln on Monday August 19, 2024 @02:54PM (#41293659)
Wow, that's disappointing. It seems there's really a lot of reasons to just accept overcommit on linux. (Browers, js engines used in various components now, databases that fork, many existing libraries not expecting allocations to fail ... and I guess they really don't after all?!)
Re:Linux Memory Overcommit (2007) by wmf on Monday August 19, 2024 @07:53PM (#41295523)
I think to fix this stuff you'd have to time travel back to 1980 or so. There's just so much software dependent on the broken behavior and a culture of not fixing things.
Re:Linux Memory Overcommit (2007) by kevingadd on Tuesday August 20, 2024 @04:55PM (#41303954)
From what I saw when running into this regularly, it seemed to be code that wasn't checking malloc return values for NULL, or code that didn't have well-defined behavior when out of memory. So I'd get weird error messages from random libraries being consumed by the applications I was using during execution, or individual operations in a larger task would fail but it would keep on chugging along.
Re:Linux Memory Overcommit (2007) by rcxdude on Monday August 19, 2024 @03:19AM (#41288599)
Do you run with swap in that case? I would suspect two possible reasons: firstly most software on linux is not run in that configuration and is thus unprepared for malloc failure: I would not be surprised if the return is not checked for many malloc() calls. Secondly, running without swap will cause bad performance (like, whole system freezing for a long time) failure modes as linux will evict cached code pages from RAM instead of rarely accessed data under memory pressure.
Re:Linux Memory Overcommit (2007) by taskforcegemini on Monday August 19, 2024 @03:44AM (#41288771)
>Secondly, running without swap will cause bad performance (like, whole system freezing for a long time)

in my experience it is exactly the opposite. unless you swap onto ssds, swapping will grind the whole system to a halt, while without swap the oom-reaper will kill the culprit and you can immediately work on the system to check/fix things. result also depends on your applications of course.

Re:Linux Memory Overcommit (2007) by wmf on Monday August 19, 2024 @07:56PM (#41295536)
The point is you need to have swap enabled but not use it. If you use swap it's bad and if you have swap disabled it's also bad. There "should" be no difference but that's not the case.
Re:Linux Memory Overcommit (2007) by lloeki on Monday August 19, 2024 @05:06AM (#41289245)
man 3 malloc:

       The malloc(), calloc(), realloc(), and reallocarray() functions
       return a pointer to the allocated memory, which is suitably
       aligned for any type that fits into the requested size or less.
       On error, these functions return NULL and set errno.
Problem is that thanks to overcommit malloc sort of always succeeds, and then many (most?) code doesn't check that malloc successfully returned and proceeds to march on towards a later obscure failure, hence below:

> It's not an orderly 'abort: malloc failed' or process termination like I would've expected. Instead, you get weird intermittent failures that don't look like OOMs

Re:Linux Memory Overcommit (2007) by CAP_NET_ADMIN on Monday August 19, 2024 @04:47AM (#41289148)
The truth is that if you're having issues with default overcommit configuration (namely overcommit_memory == 0 and overcommit_ratio == 50) your application probably sucks and you have to actually diagnose it and fix it.

"We run a pretty java-heavy environment, with multiple large JVMs configured per host. The problem is that the heap sizes have been getting larger, and we were running in an overcommitted situation and did not realize it. The JVMs would all start up and malloc() their large heaps, and then at some later time once enough of the heaps were actually used, the OOM killer would kick in and more or less randomly off one of our JVMs."

I know that 2007 may have been different times, but I'd argue that max heaps for all your JVMs running on a system probably shouldn't exceed around 88% of the total system memory. (percentage goes up as the total system memory goes up from 128GB -> 256GB -> 512GB)

Re:Linux Memory Overcommit (2007) by samus on Monday August 19, 2024 @06:30AM (#41289691)
HotSpot has a handy command line option for this issue: `-XX:+AlwaysPreTouch`, which forces the OS to actually assign memory and thus increases the likelihood to expose such issues.
Re:Linux Memory Overcommit (2007) by tredre3 on Monday August 19, 2024 @12:08PM (#41292228)
> The truth is that if you're having issues with default overcommit configuration your application probably sucks and you have to actually diagnose it and fix it.

An alternative interpretation of the issue would be that if your OS allows a single process to overcommit more than the sum of total RAM+SWAP on the system, then maybe it is it who sucks.

Re:Linux Memory Overcommit (2007) by tsss on Monday August 19, 2024 @02:45PM (#41293617)
It is a hen and egg situation. The OS has to do this because many applications have learned to rely on the behaviour and will pre-allocate huge amounts of memory that they never use. Linux practically forces applications into this because the only way to start a new process is to fork yourself which will instantly double virtual memory usage for no reason. There's also the problem that a lack of overcommit tends to lead to underutilization. I'm eagerly waiting for the day that I no longer have to size my workloads manually on kubernetes.
Re:Linux Memory Overcommit (2007) by heavenlyblue on Monday August 19, 2024 @03:41PM (#41294001)
How is forking related to overcommit?
Re:Linux Memory Overcommit (2007) by tsss on Monday August 19, 2024 @03:56PM (#41294119)
When you fork then a complete copy of the parent process is created, including all its memory. This memory is not actually copied until it is changed, but it still doubles the virtual memory usage. So without overcommit, even starting bash through a fork would immediately cause an OOM if your process uses more than 50% of physical memory.
Re:Linux Memory Overcommit (2007) by heavenlyblue on Tuesday August 20, 2024 @08:25AM (#41299411)
That's an incorrect assumption though. Overcommit is for pages that have not been accessed yet, however when forking a valid use case is to share pre-loaded, mostly read-only memory between processes.
Re:Linux Memory Overcommit (2007) by matheusmoreira on Tuesday August 20, 2024 @05:29AM (#41298346)
> the only way to start a new process is to fork yoursel

Not at all. Linux supports the clone system call which allows applications complete control over this. Linux user space chooses not to take advantage of it.

Re:Linux Memory Overcommit (2007) by crest on Monday August 19, 2024 @05:39AM (#41289417)
The problem with overcommitting beyond the sum of RAM and swap is that userspace processes can't protect themselves against the kernel's lies. You allocate memory, handle the result, access the address space and someone dies. The Linux default behaviour is an insane over-optimisation, but without it forking large processes becomes painfully expensive. The proper solution is to spawn directly through suitable system calls instead of the traditional fork() + execve() way.

Imo a good compromise to this day is to overcommit RAM with swap as fallback for correctness even if performance falls of a cliff if you use it. All of that is on top of resource limits and usage monitoring.

Re:Linux Memory Overcommit (2007) by sylware on Monday August 19, 2024 @06:07AM (#41289574)
I have been a linux user/dev for a while now, and it seems I have the wrong idea of what is memory overcommit:

For me, for a modern large CPU implementation, it simplifies a lot the userland software stack to be able to book huge virtual address spaces in userland, which are populated on page faults. If really needed, I can "release" some memory ranges of this memory virtual address space (linux munmap has some options related to just that).

I do realize I am working more and more in a 'infinite memory model' (modulo some "released" ranges from time to time).

For instance, I would be more that happy to book a few 64GiB virtual address ranges on my small 8GiB workstation.

I am talking about anonymous memory, not file backed mmaping which is another story.