Question

I'm a member in a team that develop a Delphi application. The memory requirements are huge. 500 MB is normal but in some cases it got out of memory exception. The memory allocated in that cases is typically between 1000 - 1700 MB.

We of course want 64-bits compiler but that won't happen now (and if it happens we also must convert to unicode, but that is another story...).

My question is why is there a 2 GB memory limit per process when running in a 64 bit environment. The pointer is 32 bit so I think 4 GB would be the right limit. I use Delphi 2007.

EDIT: So if I set the IMAGE_FILE_LARGE_ADDRESS_AWARE flag in Delphi by using:

{$SetPeFlags IMAGE_FILE_LARGE_ADDRESS_AWARE}

And running the resulting Exe-file on a Windows Server 2003 x64 then the application can address 4 GB ?

  • Should I set /3GB switch in boot.ini ?
  • We have tried this but on a 32 bit Windows Server 2003 and it seems to limit the windows resources. There was more exceptions for "Out of memory" with GDIError in the log. But maybe this disappear when running in a 64 bit OS ?
Was it helpful?

Solution

If you compile the Delphi application using the /LARGEADDRESSAWARE flag, it will be able to address the full 4GB on a 64-bit OS. Otherwise, when running in a WOW32, the OS assumes that the app is expecting the same environment that it would have on a 32-bit OS which means that of the 4GB of address space, 2GB is dedicated for the OS and 2GB is allocated to the application.

OTHER TIPS

The syntax in Delphi to set the LARGEADDRESSAWARE flag in the PE executable is:

{$SetPEFlags IMAGE_FILE_LARGE_ADDRESS_AWARE}

Put that in your .dpr file.

http://msdn.microsoft.com/en-us/library/aa366778(VS.85).aspx

User-mode virtual address space for each 32-bit process: 2 GB

As long as you opt into receiving 32-bit pointers with the high-bit set (by including the LARGE_ADDRESS_AWARE PE flag), there is no 2GB limit.

Direct Observation

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

Conclusion

There is no 2GB limit, on 64-bit Windows, as long as you swear you can handle pointers above $7FFFFFFF.

Note: Any code is released into the public domain. No attribution required.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top