I currently have a 32-bit .Net application (on x86 Windows) which require lots of memory. Recently it started throwing System.OutOfMemoryException's.
So, I am planning to move it to a x64 platform as 64-bit process. So will this help with the out of memory exceptions. I was reading this article from MSDN Memory limits for Windows
So, my question is if I compile a 64bit .Net application, will it have IMAGE_FILE_LARGE_ADDRESS_AWARE set as default (As the article suggests)? i.e will I be able to take advantage of the 8GB user-mode virtual address space?
The maximum memory limit for x64 processes is 8 TB, but the practical limit is far less as it depend on the amount of physical memory and the pagefile size on your system. See this post for more details on this.
The IMAGE_FILE_LARGE_ADDRESS_AWARE affect an x86 process running on a x64 OS (or a x86 OS with the /3GB directive). Your x64 application does not need to set the large address aware flag and it will be able to use all the available virtual memory on your system.
Moving to a 64 bit definitely helps cut out the OutOfMemoryExceptions, but you might want to focus on your system architecture and coding mechanisms to avoid these as it would only be a matter of time before they surface on the 64 bit machine as well.
One more advantage of moving to 64 bit machines is that with an 8 TB of virtual address space, Garbage collection for .NET happens infrequently. This does improve application performance by increasing the available virtual space for your program.
IMAGE_FILE_LARGE_ADDRESS_AWARE
is only relevant for 32 bit processes. The reason is that the address space on 32 bit Windows is split in two: 2 GB for kernel space and 2 GB for user space. To address 2 GB you need 31 bits. I.e. the pointers in a 32 bit application do not need the last bit for addressing.Some applications may have used this extra bit for custom purposes, so if the Windows memory manager suddenly hands them a real 32 bit address they can't handle that. By enabling the
IMAGE_FILE_LARGE_ADDRESS_AWARE
flag the application basically tells the OS that it can handle the entire 32 bit addressable space.If you run a
IMAGE_FILE_LARGE_ADDRESS_AWARE
application on 32 bit Windows you can access 3 GB. If you run the same 32 bit application on 64 bit Windows the process actually gets the entire 4 GB address space.If you run a 64 bit application on 64 bit Windows the user address space is 8 TB (with another 8 TB set aside for kernel address space). .NET applications set to AnyCPU will automatically be 64 bit applications on x64, so you don't have to do anything to address the additional memory.
Keep in mind, however, that the CLR imposes a 2 GB limit on any single object, so while your application may use a lot of memory, you cannot create a 2 TB array for instance. More info in this question: Single objects still limited to 2 GB in size in CLR 4.0?
Actually on an x64 OS if your application is compiled for AnyCPU then you don't need to do anything special. The JIT will create an x64 image at runtime or an x86 image when run on a 32 bit system.
Actually, that article states you will have access to 8 TB of virtual address space (and yes, this is true).