   How to efficiently handle "out of memory" scenarios in C++
  I am looking for a good way to handle "out of memory" scenarios in games. Any dynamic memory allocation is subject to trigger this scenario, but I am not sure how to handle it efficiently. My thoughts have revolved around the following:1. Having a sort of "garbage collector" that stores all dynamically allocated memory for release if the application should stop in any other way than via a normal shutdown (i.e. out of memory). This would consume even more memory than normal, so it does not really help in any good way.2. Capturing the out of memory exception via a try-catch block around each and every "new", calling a global clean-up function that destroys everything without problems (i.e. in the right order).How have you handled this sort of thing?   
  There are two kinds of "out of memory errors". There is the predictable kind: if you're about to process and combine ten 4096x4096 textures in memory with a large work buffer, then it's pretty obvious that someday, someone will not have the memory to complete this process. Whenever you start such processing, wrap it in a try-catch block and if the exception happens, display an appropriate error message and propose workarounds (reducing the workload, for instance).Then, there's the unpredictable kind: your program is run on a platform with unusually low resources and fails to perform a small allocation. I tend not to recover from such events in generic code, and only signal the issue at top level (followed by shutting down the program). However, this is because my code does not do anything worthy of recovering. If your program opens and edits some data, then you should add a try-catch block to catch anything, in order to offer to save the unsaved data if there is any before propagating the exception up.;Quote:Original post by Eldritch2. Capturing the out of memory exception via a try-catch block around each and every "new", calling a global clean-up function that destroys everything without problems (i.e. in the right order).Why?  It's already done for you.  When an exception is thrown, the function scopes are properly exited up to the point to the first applicable exception handler -- this means your local objects destructors will be invoked as usual.  If you care about dynamically allocated object, then this is exactly the reason why smart pointers are there.  std::auto_ptr is a very simple example of a smart pointer that will destroy its pointed-to object when you throw.Wrapping each new with a try/catch block is really missing the point of exceptions.  When bad_alloc is thrown, just let it bubble up to some point where you can handle it, destroying local objects on the way.   ;Quote:Original post by OxydWrapping each new with a try/catch block is really missing the point of exceptions.In the general case, letting exceptions propagate out of a function is a design issue, because the caller should not have to know the implementation details of the callee (including the ways in which this implementation may fail). Out-of-memory exceptions, being a pervasive concept, are of course not affected by this.;  If your problem is something like there are too many different objects in memory that eat it up then I suppose your options are limited.  One idea might be to check your application's memory manager* and start deleting assets that can be easily recreated (like textures or models).  These can then be loaded by the app again when the objects need them.  This could potentially be slow, but in out of memory scenarios you're always going to have to consume more processor time or real world time.  Depending on your app you could also possibly simplify the complexity of whatever you're doing if it's crippling the application. ie if there's a huge fight going on you could start releasing memory of high res textures and decals, make more shallow AI and physics checks.  Obviously a base level of quality has to be maintained, but if things are getting critical stability should be your priority.  *asuming you wrote one.   ;Quote:Original post by ToohrVyk Out-of-memory exceptions, being a pervasive concept, are of course not affected by this.Are they really, or are they a design issue as well?Given an algorithm's space complexity, space will either be sufficient or not. What remains now is simply to determine whether algorithm can progress or not.Having a file read fail is in this respect no different than running out of memory while allocating structures as defined by this file. Whether file is incomplete, or there is inadequate memory to load it is same problem, related to resource management.That said, in presence of virtual memory, exhausting available memory is typically secondary to having application grind to a halt long before due to excessive paging.An exception to this would be problems caused by fragmentation, so that certain large continuous blocks of memory cannot be allocated.But still, it's just a problem of resource management. It's simply a question of determining what resource acquisition is, and what happens if it fails. Can the application continue?   ;Quote:Original post by AntheusThat said, in presence of virtual memory, exhausting available memory is typically secondary to having application grind to a halt long before due to excessive paging.Or having it run out of virtual address space on a 32bit OS. This is getting more and more common recently. Especially since many people have more physical memory than the size of the restricted virtual address pool under XP32 and Vista32 (ie. 2 or 3 GB).;  Wrapping each and every new in try/catch is IMHO not practical.I see a few options. First, you can profile memory usage and (re)design your game to stay below a practical limit, so that you simply never exhaust (virtual) memory.Second, (this option involves a malloc()/new wrapper) you can just "safely crash" upon a failed malloc, ie. save the game, print a message and exit. The OS cleans up after you.A variation of this is to allocate a safety memory buffer, and upon failing to malloc, use this memory and print a message ("close some programs" etc), and continue.There are some techniques described in the EASTL paper.