Sponsored Link •
|
Summary
(With apologies to Smiths fans) I've been using a technique I call Memory Parachutes for some time. I'm interested in (i) whether I've stolen the technique (& name) from someone else and forgotten, and (ii) what people think of it. It's a simple strategy to increase the chances of a safe-bail-out from low memory conditions
Advertisement
|
It looks like this (in C++). Note that it's my practice to isolate the outermost catch stuff in main()
and have everything program-specific in main_()
, so that's where you want to be looking. (Not really sure why, although the fact that I made my project generator do it means I've adhered to the technique.
As you can see, it's pretty simple. You just allocate a number of different-sized blocks from the C and C++ heap(s) at the start of processing, and release them in the handler for the out-of-memory handler in the hope that you've given back enough that the cleanup code's got better chances than it would otherwise have of performing an orderly shutdown.
The use of different sized blocks is to try and cover the cases where the heap implementation maintains separate pools for small and/or medium and/or large block sizes.
Note that the heterogeneous use of the STLSoft auto_array_destructor
and scoped_handle
resource wrapper templates leaves something to be desired for neatness and clarity. I've toyed with the idea of writing
a parachutes class (with some wiz-bang expression templates!) to do it, but have never
yet found the driving motivation. That may depend on the responses to this blog entry. ;)
int main_(int argc, char **argv) { // Allocate the parachutes ::stlsoft::auto_array_destructor<char> parachute1(new char[10]); ::stlsoft::auto_array_destructor<char> parachute2(new char[100]); ::stlsoft::auto_array_destructor<char> parachute3(new char[1000]); ::stlsoft::auto_array_destructor<char> parachute4(new char[10000]); ::stlsoft::auto_array_destructor<char> parachute5(new char[100000]); ::stlsoft::scoped_handle<void*> parachute6(::malloc(10), ::free); ::stlsoft::scoped_handle<void*> parachute7(::malloc(100), ::free); ::stlsoft::scoped_handle<void*> parachute8(::malloc(1000), ::free); ::stlsoft::scoped_handle<void*> parachute9(::malloc(10000), ::free); ::stlsoft::scoped_handle<void*> parachute10(::malloc(100000), ::free); try { // . . . all the business of the application . . . } catch(blog_exception &x) { cout << "You've blogged too much recently, big mouth! Details: " << x.what() << endl; } catch(another_exception &x) { cout << "Nasty things have occured! Details: " << x.what() << endl; } catch(::std::bad_alloc &) { // Deploy the parachutes with fingers crossed that it leaves enough memory // for the delete [] parachute1.detach(); delete [] parachute2.detach(); delete [] parachute3.detach(); delete [] parachute4.detach(); delete [] parachute5.detach(); ::free(parachute6.detach()); ::free(parachute7.detach()); ::free(parachute8.detach()); ::free(parachute9.detach()); ::free(parachute10.detach()); // . . . all the actions you want to carry out to (attempt to) effect orderly shutdown . . . return EXIT_FAILURE; } return EXIT_SUCCESS; } int main(int argc, char **argv) { // The 'generic' main - carries out a minimum of things, minimising risk // of failing to be in a position to try { return main_(argc, argv); } catch(::std::exception &x) { fprintf(stderr, "Unhandled error: %s\n", x.what()); } catch(...) { fprintf(stderr, "Unhandled unknown error\n"); } return EXIT_FAILURE; }
The technique is so blindingly obvious that I struggle to accept that I've come up with it independently, but I cannot find any examples of its use in this way. One can google for "memory parachute" but that yields discussions of reserves for main-line use, whereas this is solely for helping, but not guaranteeing, orderly shutdown behaviour.
Enlightenment sought, and sorely needed.
Have an opinion? Readers have already posted 13 comments about this weblog entry. Why not add yours?
If you'd like to be notified whenever Matthew Wilson adds a new entry to his weblog, subscribe to his RSS feed.
Matthew Wilson is a software development consultant and creator of the FastFormat, Pantheios and STLSoft libraries. He is author of the books Imperfect C++ (Addison-Wesley, October 2004) and Extended STL, volume 1 (Addison-Wesley, 2007), and is currently working on his third, Breaking Up The Monolith: Advanced C++ Design Without Compromise. He has published over 60 articles on C++ and other topics, and has served as columnist and contributing editor for C/C++ Users Journal. Matthew believes that code should be discoverable and largely self-documenting, and lives up to that by being a hopeless documentor. He can be contacted via http://www.imperfectcplusplus.com/ or stlsoft@gmail.com. |
Sponsored Links
|