2017-01-23 2 views
0

Почему один и тот же код иногда запускается и иногда дает мне исключение?Почему я получаю прерывистый System.OutOfMemoryException?

Я просто запускаю тест, глядя на границы строк в памяти. Полнота моего Main.vb гласит:

Module Main 
Sub Main() 
    teststring() 
End Sub 
Sub teststring() 
    Dim strC As String 
    strC = New String("C"c, 588060752) 
End Sub 
End Module 

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

+1

Потому что это зависит от того, сколько доступной памяти есть в это время http://stackoverflow.com/questions/4486261/does-c-sharp-string-has-length-limit – Slai

+0

@Slai Хотя ваш комментарий имеет смысл (что OutOfMemory означает «Недостаточно памяти»), ваш связанный вопрос не адресует доступную память. Это дубликат другого вопроса, который не адресует доступную память. Собственно говоря, оба вопроса подразумевают, что верхний предел размера строки является фиксированным числом или, по крайней мере, фиксированным на любой заданной машине. У вас есть предложения по другой ссылке/дублирующей цели для меня? – CWilson

ответ

2

«Недостаточно памяти» может произойти, когда

  1. Вы буквально не хватает памяти, например, вы запросили строку, которая будет потреблять триллион байтов. Я не думаю, что вы можете купить сервер с терабайтами ОЗУ, еще нет. На самом деле, я считаю, что CLR ограничивает большие объекты до 2 ГБ в любом случае.

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

  3. У вас достаточно свободной памяти, но куча fragmented, и в одном месте недостаточно места для выделения непрерывной памяти.

  4. Вы превысили жесткое системное ограничение (например, выделяя StringBuilder за максимальный размер).

Это большие причины. Более подробную информацию можно найти в разделе documentation for OutOfMemoryException.

+0

Спасибо. Страницы документа и другие вопросы, которые я прочитал, не упоминали № 3, и я предположил, что автоматический GC в конце моего процесса автоматически дефрагментирует мою память. Я не могу себе представить, что явный «GC.Collect» в конце моего кода будет здесь полезен, верно? Любые предложения по чтению материалов о том, как дефрагментировать кучу в .net в качестве первой подпрограммы в приложении? Возможно, это должен быть другой вопрос. – CWilson

+0

Хмм ... Я добавил 'System.Runtime.GCSettings.LargeObjectHeapCompactionMode = System.Runtime.GCLargeObjectHeapCompactionMode.CompactOnce'' GC.Collect()' до и после 'teststring()' в 'Sub Main()' и Я все равно получаю OOMEx, раз каждые 3 или 4 раза, иногда несколько раз подряд. Кажется, это не дефрагментированная куча. – CWilson

+0

Это может быть связано с тем, что ASLR выбирает разные адреса для вещей, а иногда и фрагментирует память таким образом, чтобы предотвратить резервирование всего блока. Сбор мусора в предыдущем запуске приложения не должен иметь абсолютно никакого эффекта на последующие прогоны. –

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