Cannot catch OutOfMemoryException.

G

Guest

I have a problem with catching the OutOfMemoryException in a managed C+
application. When creating small objects on the managed heap neithe
the catch handler for OutOfMemoryException nor the UnhandledExceptio
handler is called in an out of memory situation. Instead the applicatio
writes 'Fatal out of memory' to the console and exits
Is this a bug in the runtime or am I missing something
Here is the example code

#include "stdafx.h
#using <mscorlib.dll

using namespace System
using namespace System::Collections
using namespace System::Threading
using namespace System::Diagnostics

public __gc class Test

public

static void Main()

static void Test4::OnUnhandledException( Object* pSender,
UnhandledExceptionEventArgs* pArgs )

protected

static ArrayList* ms_pList = new ArrayList()
}

void Test4::Main(

AppDomain::CurrentDomain->UnhandledException += new UnhandledExceptionEventHandler(
0, Test4::OnUnhandledException )

tr

for( int n = 0 ; n < 10; ++n

tr

Console::WriteLine("Allocating objects ...")
int i = 0
for( int m = 0; m < 100000000; ++m

ms_pList->Add(__box(i++))


Console::WriteLine("Clearing object list ...")
ms_pList->Clear()
Console::WriteLine("Garbage collection ...")
GC::Collect()

catch(OutOfMemoryException*

ms_pList->Clear()
Console::WriteLine("OutOfMemoryException caught")

catch(...

ms_pList->Clear()
Console::WriteLine("Unexpected exception caught")



catch(OutOfMemoryException*

ms_pList->Clear()
Console::WriteLine(S"OutOfMemoryException caught in Main")

catch(...

Console::WriteLine("Unexpected exception caught")


Console::WriteLine(S"Application finished normally")
Console::WriteLine(S"Press <Enter> to exit")
Console::ReadLine()


void Test4::OnUnhandledExceptio

Object* pSender,
UnhandledExceptionEventArgs* pArg


ms_pList->Clear()
GC::Collect()
Console::WriteLine(S"Unhandled exception caught:")
Console::WriteLine(S"Press <Enter> to exit")
Console::ReadLine()
Process::GetCurrentProcess()->Kill()


Best regards
Michael
 
G

Guest

Hi Michael

This is what I've used for insufficient memory. It's kind of dated, but it works! The set_new_handler( ) function was created to solve the universal problem of insufficient memory. It is defined in the new.h library. You use set_new_handler( ) by creating a function to handle the error, then passing that error-handling function's name (which is a pointer to the function) to the set_new_handler( ) function. The function you create to handle the error cannot return any values; it must be type void. Once you have created your error-handling function and your main( ) program, you must call set_new_handler( ) within your program with a statement that takes the following form:

set_new_handler( nameOfYourFunction );

Here's a quick example of mine

In main() or some other method, I have the statement

set_new_handler(noMem)

and for the method definition

void noMem(

cout << "no more memory " << endl
exit(1)
 
G

Guest

Hello deb

many thanks for your reply. I was so so impressed by all that pretty new .NET stuff tha
I really forgot about the good old _set_new_handler. But even that does not help
I tried it and got the same "Fatal out of memory". I tried both forms of _set_new_handle
_PNH _set_new_handler( _PNH ) that is implemented by the CRT as far as I know an
new_handler _set_new_handler( new_handler) that is implemented by the C++ std
Neither of them worked. As an additional test I tried allocating integers into a
std::vector<int>. In this case the new handler was called.
My interpretation of this behaviour is that the __gc heap bypasses the crt and allocate
memory by calling Windows API functions e.g. HeapCreate directly. When allocating smal
objects on the __gc heap the heap fills up so that there is no space left for creating an
OutOfMemoryException object. In this case the clr shuts down without giving you
application any chance to clean up. In my opinion this is a critical behaviour of the cl
that makes it nearly impossible to develop reliable applications using managed code

Best regards
Michael
 
S

Stu Smith

I believe there are some CLR exceptions which cannot be caught in some or
all cases: OutOfMemory, StackOverflow, and ExecutionEngine.

I seem to remember reading that future versions of the CLR might allow you
to trap more cases of these errors, but I can't find where I read it
originally. In theory the CLR should be able to recover and let you release
references etc, but in practise it's very difficult (eg collecting an object
might involve JITing the finalizer... and the memory for that has to come
from somewhere).

Sorry I can't find the original article.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top