10

I have a 32-bit application consisting one EXE and multiple DLLs. The EXE has been built with /LARGEADDRESSAWARE flag set. So I expect on a 64-bit OS I should get 4 GB of user address space. But on some 64-bit Win 7 systems I am getting only 2 GB of user address space.

The physical memory is 8 GB if that matters. What could be reason for this behavior?

phuclv
  • 37,963
  • 15
  • 156
  • 475
Naveen
  • 74,600
  • 47
  • 176
  • 233
  • Can you try `DUMPBIN /HEADERS` on your executable just to confirm the flag is set? – John Zwinck Aug 21 '14 at 11:53
  • 1
    @JohnZwinck: I confirmed with `DUMPBIN /HEADERS`, It says application can handle large address. – Naveen Aug 21 '14 at 11:56
  • I am using `GlobalMemoryStatusEx` to find the total virtual memory, if that matters. – Naveen Aug 21 '14 at 11:57
  • There is no known way to defeat /LAA. This is either a bug in your code, IsWow64Process() isn't that easy. Or an environmental problem, something like anti-malware jumps to mind. – Hans Passant Aug 24 '14 at 15:05
  • Are you sure that your 2Gb limitation isn't coming from actually being on a 32 bit system? (We have a 32 bit that uses this same flag, and have never seen a problem like yours since 64 bits systems came out. That doesn't mean your problem isn't real). There may also be a Virtual Memory per process configuration somewhere. – Ira Baxter Aug 24 '14 at 15:42
  • @IraBaxter: Nope, its a 64 bit system. – Naveen Aug 24 '14 at 16:53
  • Is it the case that Windows has heuristically decided to run the app in 32bit compatibility-mode? Check out the end of this [**link**](http://www.sevenforums.com/tutorials/316-compatibility-mode.html) for a quick way to determine and forcefully disable compatibility-mode on this app. – TheCodeArtist Aug 25 '14 at 04:10
  • I deleted my non-answer, glazed over important details. Has the IMAGE_FILE_LARGE_ADDRESS_AWARE flag been cleared? According to this MS documentation that would cause the limit to be 2GB on 64bit systems. http://msdn.microsoft.com/en-us/library/windows/desktop/aa366778(v=vs.85).aspx#memory_limits – BlamKiwi Aug 25 '14 at 04:10
  • To clarify, is it _some_ or _all_ Win7 64 bit systems you tried on? – Alexander Gessler Aug 25 '14 at 04:18
  • @AlexanderGessler: Only on some systems. Most of the systems its getting 4GB. – Naveen Aug 25 '14 at 04:25
  • Since you have totally, 8 GiB available, have you tried allocating/committing 3 GiB of RAM or more? It might be that `GlobalMemoryStatusEx` is wrong ... – Alexander Gessler Aug 25 '14 at 04:26

2 Answers2

3

After browsing through MSDN, I found the following:

On http://msdn.microsoft.com/en-us/library/windows/desktop/aa366770(v=vs.85).aspx (the page for MEMORYSTATUSEX which is used by GlobalMemoryStatusEx (http://msdn.microsoft.com/en-us/library/windows/desktop/aa366589(v=vs.85).aspx) ) the description for ullTotalVirtual is:

this value is approximately 2 GB for most 32-bit processes on an x86 processor and approximately 3 GB for 32-bit processes that are large address aware running on a system with 4-gigabyte tuning enabled.

The 4GB tuning page is: http://msdn.microsoft.com/en-us/library/windows/desktop/bb613473(v=vs.85).aspx and it says something like:

On 64-bit editions of Windows, 32-bit applications marked with the IMAGE_FILE_LARGE_ADDRESS_AWARE flag have 4 GB of address space available.

Itanium editions of Windows Server 2003: Prior to SP1, 32-bit processes have only 2 GB of address space available.

Also, the memory limits page (http://msdn.microsoft.com/en-us/library/aa366778.aspx#memory_limits) can come handy if you want to determine the total memory your system supports.

However the real useful information comes from Mark Russinowich's blog: http://blogs.technet.com/b/markrussinovich/archive/2008/07/21/3092070.aspx

While 4GB is the licensed limit for 32-bit client SKUs, the effective limit is actually lower and dependent on the system's chipset and connected devices. The reason is that the physical address map includes not only RAM, but device memory as well, and x86 and x64 systems map all device memory below the 4GB address boundary to remain compatible with 32-bit operating systems that don't know how to handle addresses larger than 4GB.

So the conclusion is that yes, this might depend on the configuration of the system. Maybe you can complete your question with a table, with the amount of the memory you get on each system and some important system configuration settings, and we might discover a pattern in this case.

Community
  • 1
  • 1
Ferenc Deak
  • 34,348
  • 17
  • 99
  • 167
-2

The problem is that an Application has a whole has to be large Adress aware - so that pointers are to be treated as unsigned.

If however on "some" system some of your used DLL is not large adressaware this renders your whole program not large address aware.

http://blogs.msdn.com/b/oldnewthing/archive/2010/09/22/10065933.aspx

  • How should that work? The exe uses 32 bit pointers until a DLL is loaded (which can be hours later) and then all pointers are changed to be 31 bit only? And following that link , Raymond Chen clearly says the switch has no effect on a DLL. – Thomas Weller Jun 03 '17 at 13:33