What do you do when malloc
returns 0 or new throws exception? Just halt or try to survive OOM condition/save the user's work?
-
4Related on Stackoverflow stackoverflow.com/questions/763159/…– ysolikCommented Oct 3, 2010 at 17:07
-
11Argh. I keep reading this as "out of mana". Too many video games in my past, I think. :)– Adam Lear ♦Commented Oct 3, 2010 at 21:11
6 Answers
I'd avoid the OOM like avoiding a crash.
Avoid doing huge chunk of work (and allocate huge chunk of memory) at once. Keep the data on the disk, trust the OS disk cache and make use of memory-mapped IO as much as possible, and only operate on a small part of data at a time. If large amounts of data need to be on-line (served with low latency) then keep them in the memory across several machines, like all the big search engine companies do. Or buy a SSD.
-
-
2There was a great debate about how to handle OOM gracefully (RAII, exception safety, blah...) but once I realized that in a multithread system with multiple dynamic modules (some from third-party), even if your thread didn't crash, there's a moment of unfortunate time where every thread will see an OOM. If even a single one decided to go ahead, you can't do anything but eye-witness.– rwongCommented Oct 7, 2010 at 14:19
Most people answering this question have probably never worked on embedded systems, where malloc returning 0 is a very real possibility. On a system I'm currently working on, there is a total of 4.25K bytes of RAM (that's 4352 bytes). I'm allocating 64 bytes for the stack, and currently have a 1600 byte heap. Just yesterday I was debugging a heap walk routine so I can follow the allocation and freeing of memory. The heap walk uses a small (30 byte) statically allocated buffer to output to a serial port. It will be turned off for the release version.
Since this is a consumer product, it better not run out of memory once the product has been released. I'm sure it will during development. In any case, about all I can do is beep the speaker a couple of times, and force a reboot.
-
2Fitting functionalities inside a small space is amazing ... it's a form of art like bonsai– rwongCommented Oct 4, 2010 at 6:24
-
6Many projects on embedded systems simply forbid dynamic allocation of memory. The only case of OOM remains stack overflow. Commented Oct 4, 2010 at 7:57
-
You are right, but especially with your first sentence: most of this simply isn’t relevant for most developers luckily. Commented Apr 25, 2012 at 13:09
To be fairly honest, in all projects I've done (keep in mind I'm not working anywhere yet), I've never considered that it could happen, and thus I suppose my programs would die a very fast death.
Besides, handling an OOM requires you to have preallocated the resources to display the error message or to save everything, which can be kind of inconvenient.
I feel that these days, memory costing less than peanuts, it's not something that should happen frequently. On the dawn of protected memory and before, maybe that was a concern, but now? The only OOM errors I've ever seen were from bugged code.
-
I can think of reclaiming some of the memory the process already has and try to either survive & recover (hard one if you dumped anything useful) or to survive as data+remnants that try to save it.– mbqCommented Oct 3, 2010 at 23:00
Checking malloc return codes is usuall pointless anyway.
Modern operating systems overcommit memory: They give processes more memory than is actually available. The memory your process is granted is virtual, all mapped to a single zeroed-out page.
It's not until you write to the memory that a physical, unique, page is allocated for your processes. If this allocation fails the kernel will terminate a process (perhaps yours!) in an attempt to find memory. At that point there's nothing you can do any more.
-
I had an idea to get into while loop with long sleep inside -- and possibly to recover if the process would survive OOM killer. I've got an impression that the processes were rather terminated because of its attempt to use 0 address, but I haven't done any solid tests.– mbqCommented Oct 3, 2010 at 22:40
-
You don't need to do anything special to deal with the OOM killer. If your process triggered it but was not selected it'll never know. Everything will just work as if there was enough memory. If on the other hand your process is selected it will be terminated and there is also nothing you can do about it. Commented Oct 4, 2010 at 7:08
-
But I can try to wait for OOM to free some memory and then try to allocate again and continue. I have an impression that malloc/new is not waiting for this to happen.– mbqCommented Oct 7, 2010 at 13:17
-
No, you can't. Your allocation will always succeed. You'll get all the virtual memory you want. It's not until you touch it that physical memory is allocated. As soon as you touch an unallocated page your process is suspended. The kernel will look for more memory, which might lead it to kill a process for more memory. If that succeeds (and it doesn't kill yours!), the page will be allocated and your process will resume. There is no way for your process to tell that this has happened. Commented Oct 7, 2010 at 14:31
-
3I'm pretty sure windows does never overcommit. It can commit more than the RAM, but not more than RAM + swapfile. Commented Apr 25, 2012 at 13:02
Unless you're developing for embedded systems, real-time systems, or systems that are so critical that failures can cost lives, or billions of dollars... Then it's probably not financially worth it to worry about out of memory conditions.
In most cases, there is little that can be done when you are out out of memory anyways, since there is no memory to create any new objects or perform any tasks that may do something. You have to weigh the cost of the app handling OOM versus the benefit you get from doing it.
-
Real-time systems don't need to check more about a malloc failure than the other systems.– zneakCommented Oct 3, 2010 at 22:58
-
@zneak - Untrue. Real-time systems have to be predictable and out of memory is not predictable unless you are specifically planning for it. Commented Oct 3, 2010 at 23:19
-
-
Free memory, cancel processes, etc.. A real-time system typically has no virtual memory or swap system because it has to be deterministic. So, it can much more easily run out of memory. Commented Oct 4, 2010 at 1:11
-
Given a certain code path that will inevitably lead to an OOM error, I don't see how crashing is a less deterministic approach than freeing memory and canceling processes.– zneakCommented Oct 4, 2010 at 5:38
I would always check for error. If something returns an error condition, then it has to be handled by your program. Even if it is a message that says "Out of memory, gotta go!", it is better than "Access violation", "core dumped", or whatever. One is an error condition you handle, the other is a bug. And the user will perceive it as such as well.
For your specific case, you could try to roll back the operation, freeing resources that you've allocated until reaching the point of failure, reporting the error, and continuing execution (maybe when you are trying to quit the application, you can give the option to exit immediately). This way, the user can decide what to do, or try to free up some memory by fiddling around, closing files, etc. Of course, how you can handle the situation is highly dependent on your program - a program that is not supposed to be interactive probably just needs to log the error and either quit, or continue.