Что происходит, когда в C # заканчивается ОЗУ?

Я не специалист по компьютерам, поэтому позвольте мне поставить этот вопрос более конкретно:

Я провожу научные вычисления, и иногда для хранения результатов вычислений требуется много памяти. Несколько дней назад у меня был выходной файл, который занимал 4 ГБ на жестком диске, но у меня такой объем оперативной памяти. Так:

  • Как CLR (или что-то еще?) Работает с памятью, когда программа, которую вы выполняете, выделяет больше памяти, чем доступно на компьютере? Есть ли своп в HD? (Я знаю, что это может замедлить мою программу, но меня интересует только проблема с памятью)
  • Это зависит от ОС, скажем, если я работаю с MONO в Linux или с VS в Windows?

Заранее спасибо!


person Girardi    schedule 14.05.2011    source источник
comment
Небольшое примечание, но вы можете сохранить файл размером 4 ГБ, не занимая все 4 ГБ памяти. Реализации файлового потока обычно имеют промежуточный буфер записи, который периодически сбрасывается на базовый диск при записи в поток.   -  person Dan Bryant    schedule 14.05.2011
comment
На самом деле, я пытался найти способ решить эту проблему с большим файлом ... Моя идея заключалась в том, чтобы разделить выходной файл на второстепенные файлы размером, скажем, 100 МБ. Стрим мог бы быть полезен, но это уже другой вопрос, и спасибо за замечание!   -  person Girardi    schedule 14.05.2011
comment
Если вы используете достаточно современную ОС, я считаю, что файловая система ОС допускает очень большие файлы и заботится обо всех «фрагментах» изнутри. Некоторые инструменты будут иметь проблемы при работе с очень большими файлами, но сами файлы должны храниться нормально. Все это не зависит от потребления памяти, что является проблемой только в том случае, если вам нужно оставить много памяти для вычислений, например, при записи файла. Вы действительно сталкиваетесь с проблемами или это просто рассмотрение возможных проблем?   -  person Dan Bryant    schedule 14.05.2011
comment
На самом деле, это просто соображение, наряду с проблемой анализа этих файлов ...   -  person Girardi    schedule 14.05.2011


Ответы (3)


Я считаю полезным думать об этом так: память - это дисковое пространство. RAM - это быстрый кеш. Вместо того, чтобы думать «когда у меня закончится ОЗУ, система переместит ее на диск», я думаю, «когда у меня будет доступная оперативная память, система переместит в нее мою дисковую память».

Это отстает от того, как думает об этом большинство людей, но я считаю, что это помогает. ОЗУ - это просто оптимизация производительности; реальный предел того, сколько памяти вы можете выделить, - это доступное дисковое пространство.

Конечно, это сложнее. В 32-битных операционных системах каждый процесс получает 2 миллиарда байт адресного пространства пользователя. (То же самое и с адресным пространством ядра, но давайте проигнорируем это.) Каждая страница памяти, к которой вы можете получить доступ, будь то в ОЗУ или на диске, должна находиться в этом адресном пространстве. Вы можете выделить более 2 миллиардов байтов, без проблем. Но вы можете адресовать только 2 ГБ за раз. Если у вас выделено 10 ГБ, то по крайней мере 8 ГБ из них не будут отображены в адресное пространство. В этом случае вам нужно отменить отображение чего-то еще, а затем отобразить то, что вы хотите, в адресное пространство, чтобы получить это.

Более того, многие объекты должны находиться в непрерывном адресном пространстве. Например, если у вас стек размером 1 МБ, в адресном пространстве должен быть миллион непрерывных байтов.

Когда у людей «заканчивается память», у них не заканчивается оперативная память; ОЗУ - это просто быстрый кеш на диске. И им не хватает места на диске; этого много. Они почти всегда находятся в ситуации, когда непрерывного адресного пространства недостаточно для удовлетворения спроса.

Диспетчер памяти CLR не реализует эти причудливые стратегии отображения и отмены отображения; По сути, вы получаете адресное пространство размером 2 ГБ и все. Если вы хотите сделать что-то необычное, скажем, с файлами с отображением памяти, вам нужно написать код для управления памятью самостоятельно.

person Eric Lippert    schedule 14.05.2011
comment
Отображение и отключение карт звучит интересно. Можете ли вы разместить ссылку на то, как использовать его в C ++? - person Dani; 14.05.2011
comment
Когда вы сказали, что диспетчер памяти CLR не реализует для вас эти причудливые стратегии сопоставления и отмены сопоставления, почему? Мне никогда не приходилось с этим сталкиваться, потому что они не могут быть реализованы универсальным, универсальным способом? Просто любопытно: О - person Joan Venge; 15.05.2011
comment
@Joan: Потому что это действительно сложная проблема - знать, что можно эффективно отображать и отображать. Предположим, вы хотите иметь в памяти видеофайл размером 10 ГБ для его редактирования. Автор программного обеспечения для редактирования может знать, что хорошо, файл имеет такую ​​структуру, поэтому давайте сопоставим столько секунд видео в адресном пространстве и отключим секунды, которые мы не редактируем прямо сейчас. В CLR нет такого понимания того, какие части памяти будут доступны в ближайшее время, а какие нет. - person Eric Lippert; 15.05.2011
comment
Спасибо, Эрик, я понимаю, что ты имеешь в виду. Определенно звучит как сложная проблема. - person Joan Venge; 16.05.2011

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

Если вы выделили больше памяти, чем можно адресовать, появится OutOfMemoryException.

Не уверен насчет Mono, но я предполагаю, что это зависит от времени выполнения и будет вести себя примерно так же (недостаточно физической памяти вызовет подкачку, слишком много выделенной вызовет исключение).

person Oded    schedule 14.05.2011
comment
Извините, что вы имеете в виду под адресуемым? спасибо - person Girardi; 14.05.2011
comment
@Girardi: в основном ваше приложение запрашивает 6 ГБ, но на вашем компьютере только 1 ГБ, вы получите OutOfMemoryException. - person Only Bolivian Here; 14.05.2011
comment
@Sergio - не совсем так. 32-битная ОС имеет адресное пространство 2 ^ 32 бита (около 4 ГБ) - если вы попытаетесь выделить больше, чем может обработать процесс, вы получите исключение OOM. Для 64-битных ОС это намного больше. Если у вас есть только 1 ГБ памяти в 32-битной ОС и вы попытаетесь использовать 3 ГБ, будет использоваться виртуальная память, то есть произойдет подкачка диска. - person Oded; 14.05.2011
comment
@Sergio: Это не обязательно правда. Теоретически вы можете использовать больше памяти, чем физически доступно вашей машине. Ограничение - это объем памяти, который может использовать ваша операционная система. Например, в 32-разрядных версиях Windows для приложений пользовательского режима доступно максимум 2 ГБ памяти. Никакая другая память не может быть адресована или использована вашим приложением. В 64-битном мире этот предел существенно повышается. - person Cody Gray; 14.05.2011
comment
@Oded: Итак, если вы попытаетесь адресовать больше памяти, чем может обрабатывать ваша ОС, вы получите это исключение, верно? - person Only Bolivian Here; 14.05.2011
comment
@Girardi - минус то, что требуется ОС и другим процессам в системе. - person Oded; 14.05.2011
comment
@ Серджио - Да. Если вы достигнете предела и попытаетесь выделить больше - бум. - person Oded; 14.05.2011

Среда выполнения просто запрашивает у операционной системы больше памяти. Операционная система обрабатывает подкачку существующего содержимого памяти на диск и иным образом меняет местами, чтобы создать больше свободной физической памяти, если это необходимо. Здесь для управляемых программ на C # /. NET происходит то же самое, что и для обычных неуправляемых программ.

Единственное отличие в мире управляемых приложений состоит в том, что среда выполнения .NET накладывает некоторые накладные расходы на память, тем самым ограничивая общий объем памяти, фактически доступной для вашего приложения. Например, сборщику мусора требуется некоторое пространство памяти для выполнения своей работы.

Так что да, это зависит от ОС, по крайней мере, до некоторой степени. Однако большинство современных операционных систем имеют довольно похожие подходы к управлению памятью.

person Cody Gray    schedule 14.05.2011