Как смоделировать исключение OutOfMemory - PullRequest
19 голосов
/ 06 мая 2010

Мне нужно провести рефакторинг своего проекта, чтобы сделать его невосприимчивым к исключению OutOfMemory.

В моем проекте используются огромные коллекции, и, изменяя один параметр, я могу сделать свою программу более точной или использовать меньше памяти ...

ОК, это фон. Я хотел бы запустить подпрограммы в цикле:

  1. Запустить подпрограммы с параметром по умолчанию.
  2. Перехватите исключение OutOfMemory, измените параметр и попробуйте запустить его снова.
  3. Выполняйте 2-ю точку, пока параметры не позволят запускать подпрограммы без исключения (обычно требуется только одно изменение).

Теперь я хотел бы проверить это. Я знаю, что могу самостоятельно сгенерировать исключение OutOfMemory, но мне хотелось бы смоделировать некоторую реальную ситуацию.

Итак, главный вопрос:
Есть ли способ установить какой-то лимит памяти для моей программы, после достижения которого автоматически выдается исключение OutOfMemory?
Например, я хотел бы установить предел, скажем, 400 МБ памяти для всей моей программы, чтобы имитировать ситуацию, когда в системе имеется такой объем памяти.
Это можно сделать?

Ответы [ 6 ]

17 голосов
/ 06 мая 2010

Это похоже на работу для ... System.Runtime.MemoryFailPoint .

http://msdn.microsoft.com/en-us/library/system.runtime.memoryfailpoint.aspx

Я думаю, что пример в ссылке соответствует вашей ситуации. Установите MemoryFailPoint на любой уровень, который вам нужен, а затем перехватите InsufficientMemoryException и соответственно настройте входные параметры.

8 голосов
/ 06 мая 2010
public void EatMemory()
{
    List<byte[]> wastedMemory = new List<byte[]>();

    while(true)
    {
        byte[] buffer = new byte[4096]; // Allocate 4kb
        wastedMemory.Add(buffer);
    }
}

Не займет много времени, если у вас нет 12 ГБ оперативной памяти:)

5 голосов
/ 06 мая 2010

Просто выделите очень большой массив. Скорее всего, вы начнете получать исключения из памяти, как только ваше приложение C # достигнет 1,2-1,6 ГБ использования ОЗУ (обычно в нижней части этого диапазона, при условии, что оно предназначено для x86).

3 голосов
/ 28 июня 2013
string value = new string('crazy', int.MaxValue);
2 голосов
/ 06 мая 2010

Хороший способ симулировать исключение нехватки памяти - запустить программу на виртуальной машине (ВМ). Вы можете установить максимальное выделение памяти для виртуальной машины на уровень, который достаточно мал, чтобы создать нагрузку на память для вашей программы и вызвать исключение.

Несколько виртуальных машин с открытым исходным кодом: QEMU , xen и kvm * ​​1008 *. Хорошей коммерческой виртуальной машиной является VMware Fusion для Mac OS X или VMware Player для Linux / Windows.

2 голосов
/ 06 мая 2010

Я хотел бы предложить другой способ взглянуть на это. Вам не обязательно исчерпывать память. Вам просто нужно отслеживать объем используемой памяти и сравнивать ее с общей системной памятью. Возможно, что-то вроде GC.GetTotalMemory будет полезно здесь, чтобы увидеть, сколько памяти использует ваше приложение. Тогда возможно, эта статья поможет получить общий объем физической памяти, доступной в вашей системе.

...