This problem has always annoyed me and, in my opinion, Microsoft really needs to do something about it. Twenty years ago it wasn't a problem because large amounts of memory just weren't accessible, that problem disappeared prior to 2009 however.
Even small to medium sized companies in 2009 had servers with 64 GB of RAM, I know I worked for one. At that same time 16 GB of RAM was becoming common on desktops. Today everything has changed and I can build a brand new desktop with 128 GB of RAM for less than $1,000. Even laptops with 64 GB of RAM are available and just now I customized a Dell laptop with 32 GB or RAM for $1250. Suffice it to say that the days of constrained RAM are long behind us and "modern" development tools have fallen way behind.
No this isn't just a rant on my part though it is at least a partial rant. I am in the unenviable position of having to develop some code for a 32 bit architecture, in .Net 4.8 no less, and part of my requirements involve using lots of RAM. My testing had revealed that in 32 bit mode on my desktop, C# was only able to allocate 1.3 GB of RAM just as the OP found. I was a little surprised to see this problem still persists a decade later.
Thanks to the good folks here (including but not limited to Julian Miller - why was his answer downvoted anyway) my 32 bit application, within the confines of the development environment even, can now allocate almost 4 GB of RAM (or 3.87 GB to be exact).
I am using Visual Studio 2022 and the key to solving the problem was the combination of Desty's and Julian Miller’s answers. It was as simple as putting the following in the post build event in my project’s property pages.
if exist "$(DevEnvDir)..\tools\VsDevCmd.bat" (
call "$(DevEnvDir)..\tools\VsDevCmd.bat"
editbin /largeaddressaware "$(TargetPath)"
)
In order to try to get an accurate assessment of the amount of RAM a 32 bit C# application would be able to allocate, I created a Windows console application test project with minimal code. I ran it on my desktop which has 16 GB of RAM with 10+ GB free at the time I ran it.
My test code follows, if you’d like to verify the results independently. Note that in order to allocate the maximum amount of RAM I had to run the code after restarting Visual Studio on occasion, maybe this is due to memory fragmentation or a leak. Note also that I realize the code looks strange but once I allocated 3 large segments of RAM I was unable to allocate another large segment so for each subsequent allocation I had to allocate numerous progressively smaller segments. I'm no memory allocation expert so I can only assume that has to do with memory fragmentation.
static void Main(string[] args)
{
long totalAllocated;
List<IntPtr> pointers = new List<IntPtr>(3000000);
pointers.Add(Marshal.AllocHGlobal(1073741823));
pointers.Add(Marshal.AllocHGlobal(1073741823));
pointers.Add(Marshal.AllocHGlobal(1060766923));
totalAllocated = 3208250569;
for (int i = 0; i < 8; i++)
pointers.Add(Marshal.AllocHGlobal(102400000));
totalAllocated += 819200000;
for (int i = 0; i < 7; i++)
pointers.Add(Marshal.AllocHGlobal(10240000));
totalAllocated += 71680000;
for (int i = 0; i < 44; i++)
pointers.Add(Marshal.AllocHGlobal(1024000));
totalAllocated += 45056000;
for (int i = 0; i < 135; i++)
pointers.Add(Marshal.AllocHGlobal(102400));
totalAllocated += 13824000;
for (int i = 0; i < 200; i++)
pointers.Add(Marshal.AllocHGlobal(10240));
totalAllocated += 2252800;
for (int i = 0; i < 300; i++)
pointers.Add(Marshal.AllocHGlobal(1024));
totalAllocated += 307200;
for (int i = 0; i < 300; i++)
pointers.Add(Marshal.AllocHGlobal(100));
totalAllocated += 30000;
for (int i = 0; i < pointers.Count; i++)
{
Marshal.FreeHGlobal(pointers[i]);
pointers[i] = IntPtr.Zero;
}
}
For the naysayers who will point to 64 bit mode, my test code could allocate a mere 5 GB of RAM in 64 bit mode. For the other naysayers, who need to stop it, who will claim no one needs to use that much RAM... we are living in the era of big data and our customers want to mine that data on their 128 GB or 256 GB desktops. The era of 4 GB has long since passed. Sadly I suspect Microsoft has no interest in making such a change to dot net.
Also, in the interest of being as thorough as possible following is a screenshot of the VS 2022 property pages of my test project showing the post build code which I had to include to enable allocation of the additional RAM.
