How to Catch Out of Memory Exception in C++

how to catch out of memory exception in c++?

Catch std::bad_alloc.

You will also need a strategy for handling the errors, since many of the things you'd like to do will require memory (even if it's only to display an error to the user before shutting down). One strategy is to allocate a block of memory at startup, and delete it in the exception handler before attempting to use more memory, so that there is some available to use.

C++ Out of Memory Exception Test

Create a test program that

  1. Creates an instance of your object
  2. Calls doubleArray() to increase the size to some number, say 65kb (how you will do this depends on the API of your data structure)
  3. Check that std::bad_alloc is thrown

To run the test program in a restricted memory environment

  1. create a user
  2. in a terminal, do ulimit -m 64. This limits the amount of memory available to the current user to 64 kb. The number depends on what you chose in step 2 above.
  3. run the program as that user

How does catching an OutOfMemoryException work?

The GC makes an analysis on the references that are used in the program, and can throw away any object that isn't used anywhere.

An OutOfMemoryException doesn't mean that the memory is completely depleted, it just means that a memory allocation failed. If you tried to allocate a large memory area at once, there may still be plenty of free memory left.

When there isn't enough free memory for an allocation, the system does a garbage collection to try to free up memory. If there still isn't enough memory for the allocation, it will throw the exception.

A StackOverflowException is not possible to handle, because it means that the stack is full, and it's not possible to remove anything from it as it is with the heap. You would need more stack space to continue running the code that would handle the exception, but there is no more.

How to get around OutOfMemory exception in C#?

If you can do it line by line, instead of saying "Read everything to memory" with File.ReadAllText, you can say "Yield me one line at time" with File.ReadLines.

This will return IEnumerable which uses deferred execution. You can do it like this:

using(StreamWriter sw = new StreamWriter(newFilePath))
foreach(var line in File.ReadLines(path))
{
sw.WriteLine(line.Replace("<", "\r\n<"));
sw.Flush();
}

If you want to learn more about deferred execution, you can check this github page.

Catching an OutOfMemory Exception C#

It may well be that you need to re-design this algorithm so that it does not attempt to put "everything" into a queue ... or, perhaps, does not use a queue at all. For instance, could an iterator be used here?

The logic of LongMethod, which is presently expressed as a double-nested loop, could be equivalently expressed as an algorithm which (given a struct of some kind to "hold state" between calls), returns (or "yields") a new object() each time.

A re-expression of this algorithm would relieve you from the obligation to generate a tremendous number of objects "all at once," and to place them in a queue "all at once." Instead, it might be possible to produce the objects one-at-a-time "on demand," and/or to produce and enqueue "some" objects while retaining the ability to produce "more of them" at some future time.

You really can't "catch" an OOM exception:   when such a thing occurs, "the program is already nine-tenths dead in the water, and almost certain to quickly finish drowning." You need some kind of an algorithm redesign that eliminates the need for "such a massive 'queue.'"

When is it OK to catch an OutOfMemoryException and how to handle it?

We all write different applications. In a WinForms or ASP.Net app I would probably just log the exception, notify the user, try to save state, and shutdown/restart. But as Igor mentioned in the comments this could very well be from building some form of image editing application and the process of loading the 100th 20MB RAW image could push the app over the edge. Do you really want the use to lose all of their work from something as simple as saying. "Sorry, unable to load more images at this time".

Another common instance that it could be useful to catch out of memory exceptions is in back end batch processing. You could have a standard model of loading multi-mega-byte files into memory for processing, but then one day out of the blue a multi-giga-byte file is loaded. When the out-of-memory occurs you could log the message to a user notification queue and then move on to the next file.

Yes it is possible that something else could blow at the same time, but those too would be logged and notified if possible. If finally the GC is unable to process any more memory the application is going to go down hard anyway. (The GC runs in an unprotected thread.)

Don't forget we all develop different types of applications. And unless you are on older, constrained machines you will probably never get an OutOfMemoryException for typical business apps... but then again not all of us are business tool developers.

To your edit...

Out-of-memory may be caused by unmanaged memory fragmentation and pinning. It can also be caused by large allocation requests. If we were to put up a white flag and draw a line in the sand over such simple issues, nothing would ever get done in large data processing projects. Now comparing that to a fatal Engine exception, well there is nothing you can do at the point the runtime falls over dead under your code. Hopefully you are able to log (but probably not) why your code fell on its face so you can prevent it in the future. But, more importantly, hopefully your code is written in a manner that could allow for safe recovery of as much data as you can. Maybe even recover the last known good state in your application and possibly skip the offending corrupt data and allow it to be manually processed and recovered.

Yet at the same time it is just as possible to have data corruption caused by SQL injection, out-of-sync versions of software, pointer manipulation, buffer over runs, and many other problems. Avoiding an issue just because you think you may not recover from it is a great way to give users error messages as constructive as Please contact your system administrator.

C++/Windows: How to report an out-of-memory exception (bad_alloc)?

  • pre-allocate the buffer(s) you need
  • link statically and use _beginthreadex instead of CreateThread (otherwise, CRT functions may fail) -- OR -- implement the string concat / i2a yourself
  • Use MessageBox (MB_SYSTEMMODAL | MB_OK) MSDN mentions this for reporting OOM conditions (and some MS blogger described this behavior as intended: the message box will not allocate memory.)

Logging is harder, at the very least, the log file needs to be open already.

Probably best with FILE_FLAG_NO_BUFFERING and FILE_FLAG_WRITE_THROUGH, to avoid any buffering attempts. The first one requires that writes and your memory buffers are sector aligned (i.e. you need to query GetDiskFreeSpace, align your buffer by that, and write only to "multiple of sector size" file offsets, and in blocks that are multiples of sector size. I am not sure if this is necessary, or helps, but a system-wide OOM where every allocation fails is hard to simulate.

C# : Out of Memory exception

Two points:

  1. If you are running a 32 bit Windows, you won't have all the 4GB accessible, only 2GB.
  2. Don't forget that the underlying implementation of List is an array. If your memory is heavily fragmented, there may not be enough contiguous space to allocate your List, even though in total you have plenty of free memory.


Related Topics



Leave a reply



Submit