32

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 ?
Roland Bengtsson
  • 5,058
  • 9
  • 58
  • 99
  • The 3GB switch in boot.ini is only for 32bit Windows, and it is required for LARGEADDRESSAWARE to work. Be aware it shrinks the space available to Windows itself on 32 bit systems. See fore example here, http://blogs.technet.com/markrussinovich/archive/2009/03/26/3211216.aspx, or read the excellent Windwos Internals by Russinovoch and Solomon. –  Apr 30 '10 at 12:11

4 Answers4

32

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.

Thomas
  • 63,911
  • 12
  • 95
  • 141
  • 5
    That's only valid on 32bit. There's no binary difference between a 3GB pointer and a 4GB pointer, so any app that can handle 3GB can do 4GB. /LARGEADDRESSAWARE is good for the full 4GB on 64bit systems without any boot up modifications. The only time you have to do /3GB is if you want to use more address space in a 32bit system. The article you linked is about ten years out of date, and only addresses 32bit systems. PAE is an entirely different system. – Puppy Apr 29 '10 at 21:17
  • @Dead: Yes, of course on 64-bit systems (http://support.microsoft.com/kb/294418) tho the original article is only 5 years out of date, not 10. :) The answer however remains wrong/incomplete in respect to it's discussion of implications on 32-bit OS's. – Deltics Apr 29 '10 at 21:24
  • 2
    @Deltics - LARGEADDRESSAWARE does not only apply to 3GB That is absolutely incorrect. http://msdn.microsoft.com/en-us/library/wz223b1z%28VS.80%29.aspx. It is an indication that the application can handle **ANY** addresses above 2GB. It is absolutely correct that if you want the full 4GB of address space on a 64-bit OS with a 32-bit application and if it can handle it, you can use the LARGEADDRESSAWARE switch. I'm not sure why you think this is incorrect. – Thomas Apr 29 '10 at 21:57
  • 1
    The answer specifically syas 64-bit OS, so what's the problem? – Mark Ransom Apr 29 '10 at 22:01
  • 1
    @Deltics - Further, the first paragraph in the article you provide completely supports what I was saying about 4GB address space and the use of 2GB for the OS and 2GB for the application. That is the default behavior on a 32-bit OS. The /3GB is a *feature* which you can *manually* enable that changes this dynamic so that up to 3GB can be allocated to an application **if** it is designed to handle the additional addressing. – Thomas Apr 29 '10 at 22:04
  • You can use {$SetPEFlags IMAGE_FILE_LARGE_ADDRESS_AWARE} instead of a compiler switch to get the same behavior. This isn't without its caveats though. Barry Kelly mentioned there may be problems with using it: http://stackoverflow.com/questions/1849344/how-can-i-enable-my-32-bit-delphi-application-to-use-4gb-of-memory-on-64-bit-wind – Zoë Peterson Apr 29 '10 at 22:13
  • 1
    @ All: Yes, no problem other than a second sentence starting with a conjunction that managed to confuse me. My bad. I have removed the offending comment not to save my blushes as much as to avoid planting the seeds of doubt in anyone's mind. – Deltics Apr 29 '10 at 23:36
15

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.

Jan Goyvaerts
  • 21,379
  • 7
  • 60
  • 72
6

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

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

Matthew Groves
  • 25,181
  • 9
  • 71
  • 121
2

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.

Ian Boyd
  • 246,734
  • 253
  • 869
  • 1,219