The Artima Developer Community
Sponsored Link

Prescriptions, Proscriptions, and Prognostications
Jumping from the top of The Parachutes
by Matthew Wilson
April 18, 2005
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.

Talk Back!

Have an opinion? Readers have already posted 13 comments about this weblog entry. Why not add yours?

RSS Feed

If you'd like to be notified whenever Matthew Wilson adds a new entry to his weblog, subscribe to his RSS feed.

About the Blogger

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.

This weblog entry is Copyright © 2005 Matthew Wilson. All rights reserved.

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use