4

I have application with very big DataTable objects, very big arrays etc.

Currently my memory usage is below 2GB.

What will happen when my application produce 4 arrays with 1GB size on 32 bit system?

Will it crash?

I know about 2GB object size limit in CLR, but what about many big objects?

I tried to just test it, I declared few big arrays, but when they are empty they seems to not use RAM. I didn't tried to fill them, i decided to just ask here.

Kamil
  • 13,363
  • 24
  • 88
  • 183
  • 6
    Why don't you just try? – Mels Apr 25 '13 at 12:37
  • Learn more about .net and maybe u need some storage like db – Roar Apr 25 '13 at 12:39
  • @Roar, data comes from SQL Server, but some things are too complicated to calculate in SQL. – Kamil Apr 25 '13 at 12:40
  • @Kamil: Maybe you need to devise a way to perform the calculation by looking at only a few data rows at a time. – Cᴏʀʏ Apr 25 '13 at 12:41
  • possible duplicate of [Is there a memory limit for a single .NET process](http://stackoverflow.com/questions/200348/is-there-a-memory-limit-for-a-single-net-process) – Chris S Apr 25 '13 at 12:43
  • 1
    Really? It is 2013 - how is this even still a question? Just switch to x64 already. There are still limits on the size of individual arrays, but the "how much RAM can it use?" is simply "how much RAM can you fit in the machine?" – Marc Gravell Apr 25 '13 at 12:44
  • @TimSchmelter I used to avr-gcc... when I declare something there - it takes memory. Im not .net professional. I didn't knew that i have to use static. Next time maybe try to help or dont write anything. – Kamil Apr 25 '13 at 12:45
  • @MarcGravell It's still a valid question IMO. I had the following requirement recently: "use Server 2003 32-bit", and I had to ask myself the very same question, *how much RAM can I use for a single process?*. – ken2k Apr 25 '13 at 12:46
  • 2
    @ken2k there comes a point when having developers spend time wondering about this costs more than just using x64 in the first place. That time was probably back around 2009 – Marc Gravell Apr 25 '13 at 12:47
  • @MarcGravell Agree, I definitely would use x64, but those limitations often come from the managers, not the developer itself. Sometimes you just can't use x64 even if you would love to. – ken2k Apr 25 '13 at 12:50
  • Maybe the question should be: do you really need this to be all in memory? – L-Four Apr 25 '13 at 13:36
  • @L-Three Im asking myself about that. All this data is result of very complicated and very slow SQLServer query, which is too complicated to divide into parts, data is related with other records so I cant just partition it. It's very complicated... – Kamil Apr 25 '13 at 13:38

5 Answers5

6

64 bit application, including managed ones, can access large memory.

32 bit application have a virtual address space of maximum 4GB. In practaice they get 2GB by default. /LARGEADRESSAWARE applicaitons can get 3GB with /3gb in boot.ini or 4GB when running on WoW64.

Managed application, even on x64 cannot allocate any single object larger than 2GB. Including arrays.

But no matter the amount of VA available at your disposal: manipulating a +2GB DataTable object is just not going to work. Use a storage engine capable of handling and manipulating large amounts of data fast, and capable of intelligent paging. Redis, Cassandra or even traditional RDBMSs are more suited for the job.

Even if you decide to manipulate the data directly in memory, you need a smarter format than DataTable.

Mr.B
  • 3,484
  • 2
  • 26
  • 40
Remus Rusanu
  • 288,378
  • 40
  • 442
  • 569
4

All 32bit applications are limited to 2GB of memory*. So no matter how you divvy the RAM up you'll run out at 2GB.

If you need more you'll need to run it on a 64bit system and compile it for 64bit.

  • Using LARGEADDRESSAWARE 32bit applications can use up to 3GB of memory, thanks Marc Gravell for reminding me of this in the comments.
Frazell Thomas
  • 6,031
  • 1
  • 20
  • 21
  • 2
    For a .Net process, it'll crash (OutOfMemoryException) before the 2GB limit. – ken2k Apr 25 '13 at 12:42
  • 1
    Actually, processes (including .NET ones) can use 3GB on x86 if you set the `LARGEADDRESSAWARE` PE header (assuming your OS has the 3GB switch enabled, which is usually simple) – Marc Gravell Apr 25 '13 at 12:45
  • Technically you can use 3GB, but on a 32 bit system you need both the application and the OS to opt into that. So nowadays this isn't really useful considering how common 64 bit processors are. What's occasionally useful is a large-address-aware 32 bit application on a 64 bit computer. – CodesInChaos Apr 25 '13 at 12:46
  • @MarcGravell Thanks, I forgot about `LARGEADDRESSAWARE` – Frazell Thomas Apr 25 '13 at 12:47
  • @FrazellThomas See http://blogs.msdn.com/b/tom/archive/2008/04/10/chat-question-memory-limits-for-32-bit-and-64-bit-processes.aspx – ken2k Apr 25 '13 at 12:47
  • It's important that once you have a 64 bit OS or a 32 bit OS with PAE you can use more than 3GB of memory in a single process. You just can't map all of it into the address space at the same time. But nowadays switching to 64 bit should be much cheaper than manually managing memory just to fit into a 32 bit process. – CodesInChaos Apr 25 '13 at 12:52
  • @CodesInChaos: I doubt managed application can use [AWE](http://msdn.microsoft.com/en-us/library/windows/desktop/aa366527(v=vs.85).aspx) in any meaningful way. – Remus Rusanu Apr 25 '13 at 12:56
1

If you use more RAM than you can address (or have), you will get an System.OutOfMemoryException exception. try this code to see:

        List<byte[]> foo = new List<byte[]>();
        for (int i = 0; i < 10000; ++i )
            foo.Add(new byte[1024*1024*1024]);
Robert J.
  • 645
  • 5
  • 13
1

Yes, it will crash. This is the sample code I tried:

class Program
{
    static byte[] arr = new byte[1024 * 1024 * 1024];
    static byte[] arr2 = new byte[1024 * 1024 * 1024];
    static byte[] arr3 = new byte[1024 * 1024 * 1024];
    static byte[] arr4 = new byte[1024 * 1024 * 1024];
    static void Main(string[] args)
    {            
        Console.ReadKey();
    }
}

This is a rather primitive test program. Unless the full amount of data is strongly reachable at once it might already be partially reclaimed by GC and therefore not crash.

You can also make them local. However, if you make a Release Build (with code optimisation) the following bit works like a charm, since unused arrays (or generally variables) may be optimised away:

static void Main(string[] args)
{
    byte[] arr = new byte[1024 * 1024 * 1024];
    byte[] arr2 = new byte[1024 * 1024 * 1024];
    byte[] arr3 = new byte[1024 * 1024 * 1024];
    byte[] arr4 = new byte[1024 * 1024 * 1024];
    Console.ReadKey();
}

In a Debug Build (no code optimisation) the above bit crashes with an OutOfMemoryException too.

Fields in contrast cannot be just left away of course. Therefore the first sample crashes no matter if the code is optimised by the compiler or not.

Matthias Meid
  • 12,455
  • 7
  • 45
  • 79
0

For the physical memory limits of different operating systems see this article Memory Limits for Windows Releases.

It is possible though, to increase the limit for .NET applications running as 32-bit, from 2GB to up to 3GB. For that you have to run editbin /LARGEADDRESSAWARE on your executable. You can find more details about it here:

Community
  • 1
  • 1
Marius Bancila
  • 16,053
  • 9
  • 49
  • 91