I am trying to use a custom new-handler to respond to out of memory errors in a program where I use the Eigen library.
When I solve an instance, I cache the results (a large dynamic size vector), so if I need to solve that instance again I already have the results. After a while it may happen that too many instances are cached, so there is not enough memory left during computation. In this case I would empty the cache (or better remove some instances).
The simplest way I came up with is to have a global variable std::map<InputType, ResultType> cache
, and to install a new-handler that empties it (unless it is already empty, then it falls back on the default handler). In this way when an allocation fails my handler frees some memory and returns, so another attempt is done to allocate memory.
However it seems that such handler is never called, instead a std::bad_alloc
exception is always thrown.
I tried this example taken from here. When using std::vector<int>
the custom handler is correctly called, and "Memory allocation failed, terminating" is printed. When using Eigen::VectorXi
I only got a std::bad_alloc
exception.
#include <Eigen/Dense>
#include <iostream>
#include <vector>
#include <new>
void handler()
{
std::cout << "Memory allocation failed, terminating\n";
std::set_new_handler(nullptr);
}
int main()
{
std::set_new_handler(handler);
try {
while(true) {
const unsigned long int Size = 100000000ul;
// Either one of the following:
// new Eigen::VectorXi(Size);
new std::vector<int>(Size);
}
} catch (const std::bad_alloc & e) {
std::cout << e.what() << '\n';
}
}
I wonder why this happens, perhaps Eigen does not use operator new
to allocate memory? I could not find anything in the documentation. Is there a way to use this technique with Eigen? Or must I catch the exception at high level, clear the cache, and perform the computation again?