Not return
It simply tried all it could and failed to make more memory available. It calls exit()
or abort()
and terminate the process.
This can be used as a fail fast strategy. If the memory is low on a system and it is known that some processes are not required (e.g.: child workers) calling abort()
will free up memory for other processes and is the fastest way to get rid of processes.
throw an exception
Throwing bad_alloc
means that the allocator cannot free any memory and if the application can somehow recover by. I personally don't care about actually catching bad_alloc
as it should not happen or I cannot do anything about it.
This could be used if you are using ancient compilers that return nullptr
when going out of memory to force them to throw. It is questionable whether this would work though.
Deinstall the new handler
Looking at the book calling set_new_handler(nullptr);
should deinstall the new handler. According to Scott Meyer it should lead to operator new
throwing the bad_alloc
exception. This should be identical to throwing the exception yourself.
Install a different new handler
Since the new_handler
is called until the allocation error is resolved (i.e.: it isn't resolved by operator new
) if an implementation provided new_handler
is not able to resolve the issue, it should propagate the condition to another layer.
If I would install a new_handler
myself, I would keep a reference (see also: get_new_handler()
)to the previous new_handler
in order to swap it back in when my algorithm is failing.
Make more memory available
The assumption here is that the application installed the new_handler
itself. The author of the new_handler
has a chance here to introspect or modify the allocated memory. So the programmer has installed the new_handler
because he knows there is some memory to free. In case everything goes wrong there is a strategy to recover from this failure.
An incomplete list of what might be going on (partial guessing):
- your operating system allows you to call the out of memory killer manually (to free memory)
- If you are using the Boehm garbage collector, you could actually call
GC_gcollect();
to force garbage collection.
- you have reserved some memory yourself that you start using now.
- you manually call delete to known expensiable unimportant objects (caches).
- you have an interpreter running like Perl, Python or Mono and call its garbage collector to tell them you are in a low on memory condition (or they install the new handler themselves on their
init()
routines).
Implementation
Here is the implementation of libstdc++.