Выделение более 1000 МБ памяти в 32-разрядной версии .СЕТЕВОЙ процесс

StackOverflow https://stackoverflow.com/questions/1109558

Вопрос

Мне интересно, почему я не могу выделить более 1000 МБ памяти в моей 32-разрядной версии .СЕТЕВОЙ процесс.Следующее мини-приложение выдает исключение OutOfMemoryException после выделения 1000 МБ.Почему 1000 МБ, а не, скажем, 1,8 ГБ?Есть ли настройка для всего процесса, которую я мог бы изменить?

static void Main(string[] args)
{
    ArrayList list = new ArrayList();
    int i = 0;
    while (true)
    {
        list.Add(new byte[1024 * 1024 * 10]); // 10 MB
        i += 10;
        Console.WriteLine(i);
    }
}

PS:Сбор мусора не помогает.

Отредактируйте, чтобы уточнить, чего я хочу: Я написал серверное приложение, которое обрабатывает очень большие объемы данных перед записью в базу данных / на диск.Вместо того чтобы создавать временные файлы для всего, я написал кэш в памяти, что делает все это сверхбыстрое.Но память ограничена, и поэтому я попытался выяснить, каковы эти ограничения.И задался вопросом, почему моя небольшая тестовая программа выдала исключение OutOfMemoryException ровно через 1000 МБ.

Это было полезно?

Решение

Ограничение виртуального адресного пространства процесса Win32 составляет 1,5 ГБ (не совсем верно).Кроме того, в .NET framework существует ограничение на процент памяти, который может использовать процесс .NET.В machine.config есть элемент processModel с атрибутом MemoryLimit, который равен % доступной памяти, которую может использовать процесс.Значение по умолчанию равно 60%.

Если компьютер, на котором вы работаете, имеет 2 ГБ памяти или вы не включили переключатель / 3GB в вашем BOOT.INI, тогда вы получите ~ 1,3 ГБ памяти на процесс.

Я не могу найти статью KB, но, если я правильно помню, .NET 1.x не может обращаться за пределами 1,5 ГБ (1,8 ГБ?), независимо от ваших настроек.

http://blogs.msdn.com/tmarq/archive/2007/06/25/some-history-on-the-asp-net-cache-memory-limits.aspx http://social.msdn.microsoft.com/Forums/en-US/clr/thread/c50ea343-b41b-467d-a457-c5a735e4dfff http://www.guidanceshare.com/wiki/ASP.NET_1.1_Performance_Guidelines_-_Caching#Configure_the_Memory_Limit

Другие советы

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

Проблема здесь заключается в нахождении непрерывного блока.Вы могли бы попробовать включить режим 3gb (что могло бы помочь ему найти еще несколько байтов), но я действительно советую не делать этого.Ответы здесь таковы:

  • используйте меньше памяти
  • используйте базу данных / файловую систему
  • используйте x64

Возможно, вы также захотите прочитать Эрика Липперта блог (у него, кажется, есть запись в блоге для каждого распространенного .ЧИСТЫЙ вопрос ...)

Недавно я проводил обширное профилирование с учетом ограничений памяти в .NET в 32-битном процессе.Нас всех засыпает идеей, что мы можем выделить до 2,4 ГБ (2 ^ 31) в приложении .NET, но, к сожалению, это не так : (.Процесс приложения располагает таким большим пространством для использования, и операционная система отлично справляется с управлением им за нас, однако у самого .NET, похоже, есть свои накладные расходы, которые составляют примерно 600-800 МБ для типичных приложений реального мира, которые превышают лимит памяти.Это означает, что как только вы выделите массив целых чисел, который занимает около 1,4 ГБ, вы должны ожидать появления OutOfMemoryException().

Очевидно, что в 64-битной версии это ограничение возникает намного позже (давайте пообщаемся через 5 лет :)), но общий размер всего в памяти также увеличивается (я нахожу, что это от ~ 1,7 до ~ 2 раз) из-за увеличения размера слова.

Что я знаю наверняка, так это то, что идея виртуальной памяти из операционной системы определенно НЕ дает вам практически бесконечного пространства для выделения в рамках одного процесса.Это сделано только для того, чтобы полные 2,4 ГБ можно было адресовать всем (многим) приложениям, запущенным одновременно.

Я надеюсь, что это понимание в какой-то степени поможет.

Первоначально я ответил на кое-что, связанное здесь (я все еще новичок, поэтому не уверен, как я должен использовать эти ссылки):

Существует ли ограничение памяти для одного .СЕТЕВОЙ процесс

Вы можете выделить ГОРАЗДО БОЛЬШЕ памяти, чем ~ 2 ГБ, создав свое приложение на 64-разрядной архитектуре, для чего требуется создать новую конфигурацию сборки в Visual Studio, и эта сборка приложения будет выполняться только в 64-разрядных версиях Windows.В .NET, используя опцию сборки по умолчанию "Любой процессор" для вашего приложения, я обнаружил, что могу выделить из кучи только около 1,5 ГБ памяти (даже на 64-разрядном компьютере с Windows), что связано с тем, что приложение фактически работает только в 32-разрядном режиме, когда оно построено в режиме "Любой процессор".Но при компиляции в архитектуру x64 вы можете выделить намного, намного больше памяти из кучи во время выполнения вашего приложения, и ниже я объясню, как создать 64-разрядную сборку для вашего приложения:

Опять же, используя обычный (по умолчанию) вариант сборки "Любой процессор" в вашем .NET project, ваше приложение ВСЕГДА будет работать в 32-разрядном режиме, даже в 64-разрядной ОС Windows.Таким образом, вы не сможете выделить более 1,5-2 ГБ оперативной памяти во время выполнения приложения.Чтобы запустить свой .NET application в истинно 64-разрядном режиме вам нужно будет зайти в диспетчер конфигурации сборки и создать тип сборки для архитектуры x64, а затем перекомпилировать вашу программу для x64, явно используя этот тип сборки.Параметр режима сборки x64 можно создать для вашего решения .NET, выполнив следующие действия:

  1. На панели Visual Studio "Обозреватель решений" щелкните правой кнопкой мыши значок решения и выберите опцию "Configuration Manager" из всплывающего меню.Это откроет диалоговое окно сборки "Configuration Manager" для файла решения .NET.
  2. В правой, верхней части диалогового окна сборки "Configuration Manager" нажмите на стрелку вниз и выберите опцию "<new>".Это откроет диалоговое окно "Платформа нового решения".
  3. В диалоговом окне "Платформа нового решения" в качестве опции "Платформа" выберите "x64" из выпадающего меню.Затем нажмите кнопку "ОК", и новый вариант сборки x64 теперь будет доступен в диалоговом окне Configuration Manager.
  4. Затем в диалоговом окне "Configuration Manager" выберите "x64" в раскрывающемся меню "Active Solution Platform".Нажмите кнопку "Закрыть".
  5. На панели Visual Studio "Обозреватель решений" щелкните правой кнопкой мыши значок проекта CS и выберите опцию "Свойства" из всплывающего меню (последняя опция в нижней части этого меню).Это откроет окно свойств проекта CS.
  6. В левой части окна свойств проекта CS перейдите на вкладку "Сборка", чтобы отобразить свойства сборки для вашего проекта code.В верхней части этого окна обратите внимание, что в поле "Платформа" теперь должно быть указано "x64" (в отличие от опции по умолчанию "Любой процессор").Если в раскрывающемся списке "Платформа" не отображается "x64", вы должны выбрать его сейчас.
  7. Затем просто создайте свой код, и в папке "bin" теперь у вас должна быть папка x64 с новой 64-разрядной сборкой вашего приложения внутри.

Использование 64-разрядной сборки вашего приложения в 64-разрядной ОС Windows позволит вашей программе выделять гораздо больше, чем ~ 2 ГБ памяти, предположительно до 2 ^ 64 адресных пространств (при наличии доступной оперативной памяти и дискового пространства, которые являются реальными ограничивающими факторами на момент написания этого ответа).

Если в вашем приложении ПО-ПРЕЖНЕМУ не хватает памяти, вы также можете увеличить размер файла подкачки памяти Windows.В Windows файл подкачки позволяет операционной системе перемещать память из ОЗУ на диск, если в ней заканчивается объем оперативной памяти.Но перемещение разделов оперативной памяти на диск и обратно требует больших временных затрат, так что это может серьезно сказаться на производительности вашего приложения.Независимо от производительности, увеличив размер страницы, вы могли бы (теоретически) сделать файл подкачки таким большим, какой имеется в свободном пространстве на C:диск вашего компьютера с Windows.В этом случае ваше приложение сможет выделить, например, до 4 ТБ памяти (или любой другой объем памяти, на который установлен размер вашего файла подкачки) во время выполнения вашей программы.Чтобы изменить параметры файла подкачки на вашем компьютере с Windows, выполните следующие действия:

  1. Откройте диалоговое окно "Свойства системы", щелкнув правой кнопкой мыши на "Этом КОМПЬЮТЕРЕ" и выбрав опцию "Свойства" во всплывающем меню.Это также можно выполнить в более поздних версиях Windows (Windows 10, Win 2012 Server и т.д.), перейдя в "Пуск" > "Панель управления" > "Система и безопасность" > "Система".
  2. В левой части диалогового окна "Система" нажмите на опцию "Дополнительные свойства системы".При этом откроется вкладка "Дополнительно" устаревшего диалогового окна "Свойства системы" для Windows.
  3. На вкладке "Дополнительно" диалогового окна "Свойства системы" нажмите кнопку "Настройки" в поле "Производительность".Это откроет диалоговое окно "Параметры производительности".
  4. В диалоговом окне "Параметры производительности" перейдите на вкладку "Дополнительно", чтобы увидеть текущие настройки размера файла подкачки памяти Windows.
  5. Чтобы увеличить размер файла подкачки, нажмите на кнопку "Изменить", и откроется диалоговое окно "Виртуальная память".
  6. В диалоговом окне "Виртуальная память" выберите диск "C:", затем в разделе "Пользовательский размер" установите "Начальный" и "Максимальный" размеры.Вы можете использовать любой размер, вплоть до максимального объема свободного места на C:диск, но внесение этого изменения зарезервирует это место для файла подкачки на жестком диске.
  7. Затем нажмите "Ок" во всех диалоговых окнах, чтобы зафиксировать новые настройки.Затем перезагрузите компьютер, чтобы убедиться, что все изменения были выполнены должным образом и что новые настройки файла подкачки работают.

В любом случае, я надеюсь, это поможет людям понять, почему они могут столкнуться с проблемой ограничения памяти объемом 1,5 - 2 ГБ в приложении .NET, даже при запуске на 64-разрядном компьютере с Windows.Это может быть очень запутанным вопросом для людей, и я надеюсь, что мое объяснение имеет смысл.Пожалуйста, не стесняйтесь присылать мне сообщения с вопросами по поводу этого ответа, если это необходимо.

Я думаю, проблема здесь в том, что это приложение будет добавлять 10 МБ с каждым выполняемым циклом, и цикл:"while (true)", что означает, что он будет добавлять эти 10 МБАЙТ до тех пор, пока приложение не будет остановлено.Таким образом, если бы он выполнялся в течение 100 циклов, он бы добавил около 1 ГБ оперативной памяти, и я предполагаю, что он сделал бы это менее чем за 30 секунд.Я хочу сказать, что вы пытаетесь использовать 10 мегабайт памяти за цикл в бесконечном цикле

Мне искренне жаль, если я не понял вашу точку зрения, но:

static void Main(string[] args)
{
    ArrayList list = new ArrayList();
    int i = 0;
    while (true)
    {
        using(byte newBt = new byte[1024 * 1024 * 10])
        {
            list.Add(newBt); // 10 MB
            i += 10;
            Console.WriteLine(i);
        }
    }
}

Вы пробовали использовать этот метод?И это может быть глупый вопрос, но зачем вы создали вечный цикл?O если вы попробуете использовать код, удалите символы >.> xD.

Источник: http://msdn.microsoft.com/en-us/library/yh598w02 (v= против80).aspx

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top