Ограничение памяти процесса 64-битного процесса

В настоящее время у меня есть 32-разрядное приложение .Net(на x86 Windows), для которого требуется много памяти. Недавно он начал бросать System.OutOfMemoryException.

Итак, я планирую перенести его на платформу x64 как 64-битный процесс. Это поможет справиться с исключениями из памяти. Я читал эту статью из MSDN Ограничения памяти для Windows

Итак, мой вопрос в том, что если я скомпилирую 64-битное приложение .Net, будет ли значение IMAGE_FILE_LARGE_ADDRESS_AWARE установлено по умолчанию (как излагается в статье)? i.e я смогу воспользоваться преимуществом виртуального адресного пространства пользовательского режима в 8 ГБ?

Ответы

Ответ 1

Максимальный предел памяти для x64-процессов составляет 8 ТБ, но практический предел намного меньше, поскольку он зависит от объема физической памяти и размера файла подкачки в вашей системе. Подробнее см. этот пост.

IMAGE_FILE_LARGE_ADDRESS_AWARE влияет на процесс x86, работающий на ОС x64 (или на ОС x86 с директивой /3GB). Вашему x64-приложению не нужно устанавливать флаг с большим адресом, и он сможет использовать всю доступную виртуальную память в вашей системе.

Ответ 2

IMAGE_FILE_LARGE_ADDRESS_AWARE применим только для 32-битных процессов. Причина в том, что адресное пространство на 32-битной Windows разделено на два: 2 ГБ для пространства ядра и 2 ГБ для пользовательского пространства. Для адресации 2 ГБ вам потребуется 31 бит. То есть указатели в 32-битном приложении не нуждаются в последнем бите для адресации.

Некоторые приложения могли использовать этот дополнительный бит для пользовательских целей, поэтому, если диспетчер памяти Windows внезапно передает им реальный 32-разрядный адрес, он не сможет справиться с этим. Включив флаг IMAGE_FILE_LARGE_ADDRESS_AWARE, приложение в основном сообщает ОС, что оно может обрабатывать все 32-разрядное адресное пространство.

Если вы запускаете приложение IMAGE_FILE_LARGE_ADDRESS_AWARE на 32-битной Windows, вы можете получить доступ к 3 ГБ. Если вы запускаете одно и то же 32-битное приложение на 64-битной Windows, процесс фактически получает все 4 ГБ адресного пространства.

Если вы запускаете 64-битное приложение на 64-битной Windows, адресное пространство пользователя составляет 8 ТБ (с другим 8 ТБ, выделенным для адресного пространства ядра). Приложения .NET, установленные в AnyCPU, автоматически будут 64-битными приложениями на x64, поэтому вам не нужно ничего делать, чтобы адресовать дополнительную память.

Имейте в виду, однако, что CLR накладывает ограничение на 2 ГБ на любой отдельный объект, поэтому, хотя ваше приложение может использовать много памяти, вы не можете создать массив из 2 ТБ, например. Дополнительная информация в этом вопросе: Отдельные объекты по-прежнему ограничены размером 2 ГБ в CLR 4.0?

Ответ 3

На самом деле, в этой статье говорится, что у вас будет доступ к 8 TB виртуального адресного пространства (и да, это правда).

Ответ 4

Собственно, на ОС x64, если ваше приложение скомпилировано для AnyCPU, вам не нужно ничего делать особо. JIT создаст образ x64 во время выполнения или образ x86 при запуске в 32-разрядной системе.

Ответ 5

    Переход на 64 бит определенно помогает вырезать OutOfMemoryExceptions, но вы можете сосредоточиться на своей архитектуре системы и механизмах кодирования, чтобы избежать их, поскольку это будет всего лишь вопросом времени, прежде чем они появятся на 64-битной машине.
         Еще одно преимущество перехода на 64-битные машины состоит в том, что с 8-битным виртуальным адресным пространством сборка мусора для .NET происходит нечасто. Это улучшает производительность приложений за счет увеличения доступного виртуального пространства для вашей программы.