2010-05-06 2 views
18

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

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

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

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

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

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

ответ

2

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

+0

Ну, мне даже не нужно сравнивать его с системной памятью, мне просто нужно знать, сколько MB ОЗУ используется моей программой. Мне нужно прочитать документ для GC ... спасибо! – Gacek

+0

ОК ... ну, так как вы искали OutOfMemoryException, я предположил, что вы хотите в какой-то момент выбежать в целях настройки для максимальной производительности. Но эй, если методы GC работают на вас, круто! – Dave

+0

Ну, я думаю, я могу использовать методы GC и самостоятельно выбросить исключение, достигнув определенного предела. Может быть, какой-то фоновой работник ... Мне нужно проверить, будет ли это работать. – Gacek

5

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

+0

ОК, но это то же самое, что я могу получить, исключив исключение OutOfMemory самостоятельно. Я хочу имитировать реальную ситуацию и протестировать ее с помощью небольших наборов данных (которые потребляют около 400 МБ оперативной памяти вместо 1,6 ГБ). – Gacek

+0

Это не будет работать надежно на 64-битной. – Thorsten79

+0

Лучше начните строить массивы с длиной 1 ГБ каждый. Вы сможете воспроизвести его довольно быстро. – Nayan

6
public void EatMemory() 
{ 
    List<byte[]> wastedMemory = new List<byte[]>(); 

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

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

+3

Om nom nom! Windows ограничивает приложения до 2 ГБ памяти на x86, и я думаю, что он немного выше на 64-битной, поэтому 12 ГБ не имеет значения. – NibblyPig

+0

Интересно, я запустил код выше, и он очень понравился моему компьютеру. Windows стала совершенно безответной, и в итоге я попал в диспетчер задач, чтобы увидеть Visual STudio, используя 3 ГБ памяти. У меня не было никаких исключений, и использование памяти продолжало ползти примерно до 3,1 ГБ, а затем прыгало обратно на 3 ГБ ... У меня 4 ГБ памяти. – NibblyPig

+0

@SLC: файл страницы, вероятно, защитил вас от этого, что, вероятно, произошло, когда вы заметили, что ваш компьютер замедлился до обхода. – Dave

16

Это выглядит как работа для ... System.Runtime.MemoryFailPoint.

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

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

+0

Кажется, что этот класс работает совершенно противоположно тому, что мне нужно. Фактически он проверяет, доступен ли определенный объем памяти (например, вызывается «MemoryFailPoint (100)», можно проверить, может ли выполняться операция, которая потребляет 100 МБ. Мне нужно проверить, сколько памяти моя программа уже потребляет. – Gacek

2

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

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

Смежные вопросы