Подтвердить что ты не робот

Почему ограничение 2 ГБ памяти при работе в 64-битной Windows?

Я участвую в команде, которая разрабатывает приложение Delphi. Требования к памяти огромны. 500 МБ - это нормально, но в некоторых случаях это исключение из памяти. Память, выделенная в этих случаях, обычно составляет от 1000 до 1700 МБ.

Мы, конечно, хотим 64-битный компилятор, но это не произойдет сейчас (и если это произойдет, мы также должны преобразовать в unicode, но это еще одна история...).

Мой вопрос в том, почему существует ограничение на 2 ГБ памяти для каждого процесса при работе в 64-битной среде. Указатель 32 бит, поэтому я думаю, что 4 ГБ будет правильным пределом. Я использую Delphi 2007.

EDIT: Поэтому, если я установил флаг IMAGE_FILE_LARGE_ADDRESS_AWARE в Delphi, используя:

{$SetPeFlags IMAGE_FILE_LARGE_ADDRESS_AWARE}

И запустив полученный Exe файл на Windows Server 2003 x64, приложение может обратиться в 4 ГБ?

  • Должен ли я установить/3GB-переключатель в boot.ini?
  • Мы пробовали это, но на 32-битном Windows Server 2003 и, похоже, ограничиваем ресурсы Windows. За исключением "Out of memory" с GDIError в журнале было больше исключений. Но может быть, это исчезнет при работе в 64-битной ОС?
4b9b3361

Ответ 1

Если вы скомпилируете приложение Delphi с помощью флага /LARGEADDRESSAWARE, он сможет адресовать полный 4 ГБ в 64-разрядной ОС. В противном случае, при работе в WOW32, ОС предполагает, что приложение ожидает того же окружения, что и у 32-разрядной ОС, что означает, что из 4 ГБ адресного пространства для ОС выделено 2 ГБ, а 2 ГБ выделяется приложения.

Ответ 2

Синтаксис в Delphi для установки флага LARGEADDRESSAWARE в исполняемом файле PE:

{$SetPEFlags IMAGE_FILE_LARGE_ADDRESS_AWARE}

Поместите это в ваш .dpr файл.

Ответ 4

Пока вы выбираете 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;

enter image description here

Заключение

В 64-битной Windows нет ограничения на 2 ГБ, если вы клянетесь, вы можете обрабатывать указатели выше $7FFFFFFF.

Примечание. Любой код выпущен в общедоступном домене. Не требуется атрибуция.