Почему 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 31

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.

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