Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
247 views
in Technique[技术] by (71.8m points)

c# - How does catching an OutOfMemoryException work?

I am a little bit confused about the fact that we can just catch an OutOfMemoryException using a try/catch block.

Given the following code:

Console.WriteLine("Starting");

for (int i = 0; i < 10; i++)
{
    try
    {
        OutOfMemory();
    }
    catch (Exception exception)
    {
        Console.WriteLine(exception.ToString());
    } 
}

try
{
    StackOverflow();
}
catch (Exception exception)
{
    Console.WriteLine(exception.ToString());
}

Console.WriteLine("Done");

The methods I used to create the OutOfMemory + StackOverflowException:

public static void OutOfMemory()
{
    List<byte[]> data = new List<byte[]>(1500);

    while (true)
    {
        byte[] buffer = new byte[int.MaxValue / 2];

        for (int i = 0; i < buffer.Length; i++)
        {
            buffer[i] = 255;
        }

        data.Add(buffer);
    }
}

static void StackOverflow()
{
    StackOverflow();
}

It prints out the OutOfMemoryException 10 times and then terminates due to the StackOverflowException, which it can't handle.

The RAM graph looks like that while executing the program: graph showing that memory gets allocated and released 10 times

My question now it why are we able to catch the OutOfMemoryException? After catching it we can just go on execute any code we want. As proven by the RAM graph, there is memory released. How does the runtime know which objects it can GC and which are still required for further execution?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The GC makes an analysis on the references that are used in the program, and can throw away any object that isn't used anywhere.

An OutOfMemoryException doesn't mean that the memory is completely depleted, it just means that a memory allocation failed. If you tried to allocate a large memory area at once, there may still be plenty of free memory left.

When there isn't enough free memory for an allocation, the system does a garbage collection to try to free up memory. If there still isn't enough memory for the allocation, it will throw the exception.

A StackOverflowException is not possible to handle, because it means that the stack is full, and it's not possible to remove anything from it as it is with the heap. You would need more stack space to continue running the code that would handle the exception, but there is no more.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

57.0k users

...