I am creating a .NET application (C#) that needs to use a lot of RAM. I recently knew that on 32-bit versions of Windows XP I can only use 2 GB, unless I use the /3Gb
switch, and set the IMAGE_FILE_LARGE_ADDRESS_AWARE
flag in the executable header. But since I'm developing a .NET application, I guess I cannot modify the executable directly, can I? So, what should I do to allow my application to utilize the 3 GB?
views:
1588answers:
7/3GB switch is on the OS bootloader, not on your applications. (EDIT: It is also present in native C/C++ compilers, but not C# compiler) As far as your app is concerned, it will request memory and the OS will give it to your process. However you have access to 1 more gig (potentially, you don't always get 3gig depending on your hardware peripherals) before your program uses virtual memory.
As Marc Gavell has pointed out to me, you may need to run the command "editbin /LARGEADDRESSAWARE my.exe" as a post build option on your exe to enable this. Found a reference to an MS person speaking about it here: MS Forums
Might I suggest you look at your program and see whether you could rearchitect it to use less memory. Perhaps you could deal with a dataset in smaller chunks instead of trying to load the whole thing at once into memory?
An .NET exe is still a standard PE file; so you could try using editbin /LARGEADDRESSAWARE
to set the flag, but note that this won't work if you are using something like ClickOnce (since that maintains a cryptographic hash of the files).
However, note that you'll still have the same .NET limits in terms of the maximum size of a single object/array. For huge amounts of memory, x64 is a better idea.
As far as I remember, /3GB switch can only be used for Windows Server (2000 or 2003) but not for Windows XP. You need to write /3GB at the end of the boot.ini file. This way, for the applications, OS enables more memory which it normally allocates to use for kernel processes. However, /3GB does not mean you can use 3GB of memory for your application, it just can use more memory but it doesn't necessarily have to be 3GB. For .net applications, again as far as I remember, with /3GB switch you can use up to 1.8GB of memory. By the way, you might also want to check /PAE switch.
Well, I'm not sure about this, but this is what I think:
A .NET executable can be compiled in two ways - platform specific and platform independant. By default they are platform independant, and the code is (as mentioned in other answers) JIT'ed to platform specific code when running the program.
Now, for example, if your executable is one of these platform-independant ones, and you run it on a 64-bit OS, it will be JIT'ed to 64-bit code, right? Thus it will be able to address way more that 3GB of RAM.
What I'm trying to say is - I don't think it matters at all what is written in the PE header. The actual amount of available RAM is determined by the .NET runtime, which in turn looks at the current platform and produces the best JIT'ed code it can.
I think you shouldn't worry about the /3GB switch as .NET will take care of it for you. Trust in the .NET! :)
You could try using Remoting via Named Pipes and get more memory by physically having more processes.
If you are doing any form of interop (and normal .Net sockets count here) you should create an object cache (e.g. with sockets a byte[] buffer) that allocates a large amount of these objects at application startup.
You should read this article.
You should also increase your process' maximum working set size: see the SetProcessWorkingSetSize API.
Is "editbin /LARGEADDRESSAWARE my.exe" working for C# applications? I was told that it works only for C++ applications. Could you please tell me if we need to update boot.ini file as well?
Thanks!