Почему "Любой процессор (предпочтительно 32-разрядный)" позволяет мне выделять больше памяти, чем x86 в.NET 4.5?

Согласно многим ответам SO и этому широко цитируемому сообщению в блоге, приложение.NET 4.5, созданное для "Любого ЦП" с выбранной опцией "предпочесть 32-разрядный", будет работать как 32-разрядный процесс как на 32-разрядном, так и на 64-разрядном системы (в отличие от.NET 4.0 и более ранних версий). Другими словами, x86 и Any CPU с выбранным "предпочтительным 32-битным" эквивалентны (игнорируя, может ли он работать на ARM).

Тем не менее, мои тесты показали, что в 64-битной системе приложение Any CPU предпочитает 32-битное (которое, как я подтверждаю, работает 32-битное) может выделить больше памяти, чем x86. Я написал консольное приложение.NET 4.5 C#, которое выделяет 10 МБ байтовых массивов в цикле (сохраняя ссылки, конечно) до тех пор, пока оно не достигнет OutOfMemoryException, и запустил его в 64-битной системе с большим количеством оперативной памяти. При сборке в виде x86 он выделяется примерно на 1,2 ГБ. Тот же код, что и "Любой процессор (предпочтительнее 32-разрядный)", получает до 1,5 ГБ.

Почему разница?

1 ответ

Решение

Оказывается, что в Visual Studio 2015 сборка с использованием AnyCPU (предпочтительно 32-разрядной) устанавливает бит IMAGE_FILE_LARGE_ADDRESS_AWARE в исполняемом файле (эквивалентно выполнению editbin /LARGEADDRESSAWARE на нем), тогда как это не для сборки x86. Это может быть подтверждено dumpbin /HEADERS и ищет строку "Приложение может обрабатывать большие (>2 ГБ) адреса".

Это не относится к Visual Studio 2013. Это изменение явно недокументировано.

Теоретически, это должно дать CLR дополнительные 2 ГБ для игры. Я не знаю, почему выделяемая память увеличивается только примерно на 300 МБ.

Другие вопросы по тегам