Я немного смущен тем, что мы можем просто поймать OutOfMemoryException
используя блок try/catch.
Учитывая следующий код:
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");
Методы, которые я использовал для создания 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();
}
Он печатает OutOfMemoryException
10 раз, а затем завершается из-за OutOfMemoryException
StackOverflowException
, с которым он не может справиться.
График RAM выглядит так, как при выполнении программы:
Мой вопрос теперь, почему мы можем поймать OutOfMemoryException
? После этого мы можем просто выполнить любой код, который мы хотим. Как доказано графиком ОЗУ, выпущена память. Как среда выполнения знает, какие объекты она может GC и которые все еще необходимы для дальнейшего выполнения?