29

I heard from someone that the maximum array size in .NET is 4 GB? Just wondering if that is true. You wouldn't dream of doing this on 32-bit .NET but on a 64-bit system with 12 GB of RAM, maybe, just maybe you might want to do this. :-)

Keith Hill
  • 194,368
  • 42
  • 353
  • 369
  • 7
    It might be worth noting for future visitors of this post that .net 4.5 removes this limitation if I am reading it correctly. http://msdn.microsoft.com/en-us/library/hh285054(v=vs.110).aspx – TravisWhidden Feb 23 '12 at 04:50
  • 2
    @TravisWhidden well, now that it's the future, I can tell that the limitation is still there unfortunately... – Thomas Ayoub Jun 17 '15 at 15:18

3 Answers3

46

An array could theoretically have at most 2,147,483,647 elements, since it uses an int for indexing. The actual limit is slightly lower than this, depending on the type contained within the array.

However, there is a 2GB maximum single object restriction in the .NET CLR, even in 64bit. This was done by design.

You can easily make an IList<T> implementation that, internally, keeps multiple arrays, and allows you to grow beyond the 2GB single object limit, but there is not one in the framework itself.

Typically, however, this is not a real problem. Most of the time, you'll have arrays pointing to large classes - so the array is just holding references. This would mean your array can effectively point to many, many GBs of memory - but the array itself cannot be >2GB.


Note that, as of .NET 4.5, there is a new option available where 64bit applications can opt-in: gcAllowVeryLargeObjects. With this new option set, it is possible to get UInt32.MaxValue (4,294,967,295) elements in a multi-dimensional array, though a single dimensional array is still limited to 2,146,435,071 elements (2,147,483,591 for single byte arrays or arrays of a struct containing nothing ut a byte).

The new rules with this option are:

  • The maximum number of elements in an array is UInt32.MaxValue.
  • The maximum index in any single dimension is 2,147,483,591 (0x7FFFFFC7) for byte arrays and arrays of single-byte structures, and 2,146,435,071 (0X7FEFFFFF) for other types.
  • The maximum size for strings and other non-array objects is unchanged.
shoelzer
  • 10,648
  • 2
  • 28
  • 49
Reed Copsey
  • 554,122
  • 78
  • 1,158
  • 1,373
  • Cant you index an array using a long (Int64)? You can certainly use Array.GetVaue() with a long which allows many more elements - which there could still be and the array would be < 2GB, for example in a bool[] – markmnl Nov 10 '10 at 09:31
  • @Mrk Mnl: Yes, you can use long indexing, but the CLR implementation does not allow you to use arrays larger than int indexing anyways. Arrays in Microsoft's .NET implementation are always limited to 2147483647 elements. – Reed Copsey Nov 10 '10 at 16:30
  • @Mrk Mnl: Most likely because it's not CLS compliant. – Reed Copsey Nov 11 '10 at 18:04
  • It's silly that trying to allocate a larger array raises OutOfMemoryException when actual memory isn't the problem. I think it should raise a "MaximumObjectSizeException" or something similar. – Magnus Krisell Apr 21 '12 at 13:40
  • 1
    Although the answer was correct at the time of writing, .NET 4.5 removes this limit - see Mark Gravell's answer. – Ian Griffiths Jul 21 '12 at 17:22
  • 2
    @IanGriffiths That changes the maximum SIZE of an array, but it still has maximum limits on # of items. I edited with more details and updating for 4.5. – Reed Copsey Jul 23 '12 at 22:49
  • The new feature in .NET 4.5 is most interesting when the array element type is a value type with size greater than 1 byte, or a reference type. For example `new ulong[333222111]` will not give problems with index size, but exceeds the 2 GB limit (so needs `gcAllowVeryLargeObjects`). Same with `new string[333222111]` (reference type). – Jeppe Stig Nielsen Dec 18 '13 at 14:34
  • @markmnl Note that in .NET, each `Boolean` (`bool`) in a Boolean array takes up a whole byte, not just 1/8 of a byte. – Jeppe Stig Nielsen Dec 18 '13 at 14:35
  • What about a more complicated object like a DataTable? Is that also limited to 2 GB? – Chris Smith Jul 24 '15 at 00:00
  • @ReedCopsey Thanks for the "by design" link which is enlightening. Is the [LongLength](https://msdn.microsoft.com/en-us/library/system.array.longlength(v=vs.110).aspx) property on array's useful at all? Maybe on multidimensional arrays? – Louis Somers Dec 05 '15 at 19:21
  • A byte array can have a maximum size of Int32.MaxValue - 57 – Tarik Nov 02 '16 at 06:49
  • As a sidenote, the description of the page seems to be wrong... `new float[2146435071]` works, `new float[2146435071 + 1]` doesn't, but the maximum index of `new float[2146435071]` is `2146435070` (and with the word _index_ in arrays Microsoft always means the "index" and not the "length", see the various methods of the `Array` class) – xanatos Dec 29 '20 at 11:13
8

In versions of .NET prior to 4.5, the maximum object size is 2GB. From 4.5 onwards you can allocate larger objects if gcAllowVeryLargeObjects is enabled. Note that the limit for string is not affected, but "arrays" should cover "lists" too, since lists are backed by arrays.

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
0

The maximum size of any one object in .NET is 2GB.

This, of course, puts a hard cap on how large you can make a raw array.

You can make an "array of arrays" (and even create your own indexer to access them as though it was one contiguous array) pretty much as large as you like if you define your own class for it.

Anon.
  • 58,739
  • 8
  • 81
  • 86
  • 1
    Why then did Microsoft see fit to add LongLength to the array object in .NET 2.0? – Keith Hill Feb 26 '10 at 00:50
  • 1
    @Keith: I suspect that was there for future-proofing, although it's not really usable in any meaningful way in the current CLR implementations (including CLR 4). – Reed Copsey Feb 26 '10 at 00:53
  • 1
    @Keith: "Why did Microsoft add LongLength?" - I'd guess that it's because the 2GB object size limit is an implementation detail, not a contracted limit. It might also be that at some point they planned to up the limit, but found that the benefits weren't worth the problems they ran into (or something along those lines). – Michael Burr Feb 26 '10 at 00:56
  • 1
    As of .NET 4.5, LongLength is now useful - see Marc Gravell's answer – Ian Griffiths Jul 21 '12 at 17:21
  • This answer should be removed, it is just not valid any more – Chris Marisic Apr 27 '15 at 21:27