Почему 2 ГБ памяти ограничивают при работе в 64-битной Windows?
Я являюсь членом команды, которая разрабатывает приложение Delphi. Требования к памяти огромны. 500 МБ-это нормально, но в некоторых случаях он получил исключение из памяти. Объем памяти, выделяемой в таких случаях, обычно составляет от 1000 до 1700 Мбайт.
Мы, конечно, хотим 64-битный компилятор, но это не произойдет сейчас (и если это произойдет, мы также должны преобразовать в unicode, но это другая история...).
Мой вопрос заключается в том, почему существует ограничение на 2 ГБ памяти для каждого процесса при работе в 64-битном режиме окружающая среда. Указатель 32-битный, поэтому я думаю, что 4 ГБ будет правильным пределом. Я использую Delphi 2007.
Редактировать: Поэтому, если я установлю флаг IMAGE_FILE_LARGE_ADDRESS_AWARE в Delphi, используя:
{$SetPeFlags IMAGE_FILE_LARGE_ADDRESS_AWARE}
И запуск результирующего Exe-файла на Windows Server 2003 x64, то приложение может адресовать 4 ГБ ?
- Должен ли я установить переключатель /3GB в boot.Ини ?
- мы пробовали это, но на 32-битном Windows Server 2003, и это, кажется, ограничивает ресурсы windows. Там был больше исключений для "Из памяти" с GDIError в журнале. Но, может быть, это исчезнет при работе в 64-битной ОС ?
4 ответа:
Если вы скомпилируете приложение Delphi, используя флаг /LARGEADDRESSAWARE, оно сможет адресовать все 4 ГБ на 64-битной ОС. В противном случае при работе в WOW32 ОС предполагает, что приложение ожидает ту же среду, что и в 32-разрядной ОС, что означает, что из 4 ГБ адресного пространства 2 ГБ выделено для ОС и 2 ГБ выделено для приложения.
Синтаксис в Delphi для установки флага LARGEADDRESSAWARE в исполняемом файле PE:
{$SetPEFlags IMAGE_FILE_LARGE_ADDRESS_AWARE}
Положите это в свой .файл ДНР.
Http://msdn.microsoft.com/en-us/library/aa366778 (VS.85).aspx
Виртуальное адресное пространство пользовательского режима для каждого 32-разрядного процесса: 2 ГБ
До тех пор, пока вы решаете получать 32-разрядные указатели с набором старших битов (включая флаг
LARGE_ADDRESS_AWARE
PE), ограничения в 2 ГБ не существует.Прямое Наблюдение
var p: Pointer; n: Int64; begin p := Pointer($D0000000); //Above the 2GB line; and the 3GB line! p := VirtualAlloc(p, 1024, MEM_COMMIT or MEM_RESERVE, PAGE_READWRITE); if p = nil then RaiseLastWin32Error; n := Cardinal(p); ShowMessage(IntToHex(n, 16)); end;
Заключение
В 64-битной Windows нет ограничения на 2 ГБ, если вы клянетесь, что можете обрабатывать указатели выше $7FFFFFFF.
Примечание : любой код становится общедоступным. Атрибуция не требуется.