Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Allocating more than 1,000 MB of memory in 32-bit .NET process

Tags:

I am wondering why I'm not able to allocate more that 1,000 MB of memory in my 32-bit .NET process. The following mini application throws an OutOfMemoryException after having allocated 1,000 MB. Why 1,000 MB, and not say 1.8 GB? Is there a process-wide setting I could change?

static void Main(string[] args)
{
    ArrayList list = new ArrayList();
    int i = 0;
    while (true)
    {
        list.Add(new byte[1024 * 1024 * 10]); // 10 MB
        i += 10;
        Console.WriteLine(i);
    }
}

PS: Garbage collecting does not help.

Edit, to clarify what I want: I have written a server application which deals with very large amounts of data before writing to database/disk. Instead of creating temporary files for everything, I have written an in-memory cache, which makes the whole thing super-fast. But memory is limited, and so I tried to find out what the limits are. And wondered why my small test program threw the OutOfMemoryException after exactly 1,000 MB.

like image 505
Stefan Schultze Avatar asked Jul 10 '09 13:07

Stefan Schultze


People also ask

How much memory can a .NET application use?

Since . NET 1.0 the memory limit of . NET object is 2GB. This means you cannot for example create array which contains elements with more than 2GB in total.

What is the maximum memory size for a process?

The 2 GB limit refers to a physical memory barrier for a process running on a 32-bit operating system, which can only use a maximum of 2 GB of memory. The problem mainly affects 32-bit versions of operating systems like Microsoft Windows and Linux, although some variants of the latter can overcome this barrier.

What is the maximum size malloc can allocate?

The malloc() function reserves a block of storage of size bytes. Unlike the calloc() function, malloc() does not initialize all elements to 0. The maximum size for a non-teraspace malloc() is 16711568 bytes.


2 Answers

Having enormous blocks of memory is never a good idea, even in 64bit. You get big problems with contiguous memory and fragmentation.

The problem here is finding a contiguous block. You could try enabling 3gb mode (which might help it find a few more bytes) but I really advise against it. The answers here are:

  • use less memory
  • use a database/file system
  • use x64

You might also want to read Eric Lippert's blog (he seems to have a blog entry for every common .NET question...)

like image 121
Marc Gravell Avatar answered Oct 02 '22 20:10

Marc Gravell


The virtual address space limit of a Win32 process is 1.5GB (not entirely true). Additionally in the .NET frameworks there is a limiter to the % of memory a .NET process can consume. The machine.config has a processModel element with an attribute memoryLimit which is the % of available memory a process can consume. The default value is 60%.

If the machine you're running on has 2GB of memory or you haven't enabled the /3GB switch in your BOOT.INI then you're going to get ~1.3GB of memory per process.

I can't find the KB article but if I remember correctly .NET 1.x cannot address beyond the 1.5GB (1.8GB?) limit regardless of your settings.

http://blogs.msdn.com/tmarq/archive/2007/06/25/some-history-on-the-asp-net-cache-memory-limits.aspx http://social.msdn.microsoft.com/Forums/en-US/clr/thread/c50ea343-b41b-467d-a457-c5a735e4dfff http://www.guidanceshare.com/wiki/ASP.NET_1.1_Performance_Guidelines_-_Caching#Configure_the_Memory_Limit

like image 38
MyItchyChin Avatar answered Oct 02 '22 21:10

MyItchyChin