41

Anybody know what the max number of items in a List is?

How do I increase that size? Or is there a collection that takes infinite items? (as much as would fit in memory, that is)

EDIT:

I get an out of memory exception when Count = 134217728 in a list of ints. got 3Gb of RAM of which 2.2 are in use. Sound normal

Tony The Lion
  • 61,704
  • 67
  • 242
  • 415
  • @Tony - you mention (comments) that your memory must be running out fast... what actual problem are you seeing? – Marc Gravell Jan 05 '10 at 21:34
  • @Marc, edited my post with problem – Tony The Lion Jan 05 '10 at 21:38
  • Updated answer re your update – Marc Gravell Jan 05 '10 at 21:44
  • Just curious now, why do you need such a giant list? – Mathias Jan 05 '10 at 21:44
  • 4
    RAM is completely irrelevant. The number of chips you have in your machine has almost nothing to do with the size of the virtual address space; that's what you're running out of. http://blogs.msdn.com/ericlippert/archive/2009/06/08/out-of-memory-does-not-refer-to-physical-memory.aspx – Eric Lippert Jan 06 '10 at 00:39
  • @Eric, thanks for pointing that out! How could I forget about virtual address space?!! – Tony The Lion Jan 06 '10 at 01:05
  • I needed that list because I was writing a solution to a problem on Project Euler, trying to wack each answer to a recursive algo into a list, turned out that there was way too many answers to wack in a list. Waaay too many. Hahah – Tony The Lion Jan 06 '10 at 01:06

6 Answers6

62

List<T> will be limited to the max of an array, which is 2GB (even in x64). If that isn't enough, you're using the wrong type of data storage. You can save a lot of overhead by starting it the right size, though - by passing an int to the constructor.

Re your edit - with 134217728 x Int32, that is 512MB. Remember that List<T> uses a doubling algorithm; if you are drip-feeding items via Add (without allocating all the space first) it is going to try to double to 1GB (on top of the 512MB you're already holding, the rest of your app, and of course the CLR runtime and libraries). I'm assuming you're on x86, so you already have a 2GB limit per process, and it is likely that you have fragmented your "large object heap" to death while adding items.

Personally, yes, it sounds about right to start getting an out-of-memory at this point.


Edit: in .NET 4.5, arrays larger than 2GB are allowed if the <gcAllowVeryLargeObjects> switch is enabled. The limit then is 2^31 items. This might be useful for arrays of references (8 bytes each in x64), or an array of large structs.

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • 7
    No, I mean 2GB of memory, as imposed by the CLR. For reference-types, that means (on x64) 8 bytes per reference, so divide it a few more times ;-p – Marc Gravell Jan 05 '10 at 21:36
  • 4
    An interesting side-effect of the above is that **in theory** you could have more references in an array in x86. In reality, on x86 you're never going to manage to allocate an array that big *and* have space for any useful (and different) objects to put in it... In either case, a list/array of this size is just plain wrong. – Marc Gravell Jan 05 '10 at 21:40
  • I've never seen a single .NET process allocate more than about 1.5Gb (at least within a single AppDomain). Most .NET processes seem to run out of memory in their local address space well before they reach the limit of array sizes for storing references. – LBushkin Jan 05 '10 at 21:43
  • 3
    For more details see this question http://stackoverflow.com/questions/1087982/single-objects-still-limited-to-2-gb-in-size-in-clr-4-0 – Brian Rasmussen Jan 05 '10 at 21:45
  • 1
    BTW, doesn't the Mono CLR allow you to allocate array larger than 2Gb. I thought they support this, and actually implement the Array.LongLength property as a result. – LBushkin Jan 05 '10 at 21:47
  • Thanks Brian - the accepted answer has some points that tie in directly to the issue of approaching 1GB. Good reference. – Marc Gravell Jan 05 '10 at 21:48
  • where can you see how much memory a list is taking? – Rod Mar 15 '19 at 20:47
  • @Rod you can get a good estimate via `list.Capacity * Unsafe.SizeOf()` (using System.Runtime.CompilerServices.Unsafe) – Marc Gravell Mar 15 '19 at 22:41
  • Index of a List is of type Int32 with a MaxValue of `2.147.483.647`....why is that not the answer? Question was "max number of items". Is it possible to have more items, if so, how? Memory is something different, although both limit the List of course. – MrCalvin Aug 17 '22 at 15:54
1

It's limited only by memory.

edit: or not, 2Gb's is the limit! This is quite interesting, BigArray, getting around the 2GB array size limit

Paul Creasey
  • 28,321
  • 10
  • 54
  • 90
  • then my memory must be running out fast?!? – Tony The Lion Jan 05 '10 at 21:33
  • 1
    Not just limited by memory, there is a hard limit due to the underlying array backing. – Paolo Jan 05 '10 at 21:40
  • For anyone interested in that link: https://learn.microsoft.com/en-us/archive/blogs/joshwil/bigarrayt-getting-around-the-2gb-array-size-limit I would edit the answer, but "Suggested edit queue is full" – Walkman Jun 20 '22 at 09:11
1

The List limit is 2.1 Billion objects or the size of your memory which ever is hit first.

Blounty
  • 3,342
  • 22
  • 21
  • No that is not correct. No object can be larger than 2 GB so the array holding the actual references or values will limit this significantly. – Brian Rasmussen Jan 05 '10 at 21:46
  • Not exactly, it varies with the type of object stored... List limit for `int` for example is only 268435456 for 64 bit processes. – Vlad Apr 02 '14 at 16:17
1

On a x64 Machine, using .Net Framework 4 (Not the Client Profile), compiling for Any CPU in Release mode, I could chew up all the available memory. My process is now 5.3GB and I've consumed all available memory (8GB) on my PC. It's actually a Server 2008 R2 x64.
I used a custom Collection class based on CollectionBase to store 61,910,847 instances of the following class:

public class AbbreviatedForDrawRecord {
    public int DrawId { get; set; }
    public long Member_Id { get; set; }
    public string FactorySerial { get; set; }

    public AbbreviatedForDrawRecord() {

    }

    public AbbreviatedForDrawRecord(int drawId, long memberId, string factorySerial) {
        this.DrawId = drawId;
        this.Member_Id = memberId;
        this.FactorySerial = factorySerial;
    }
}
Achilles
  • 1,554
  • 1
  • 28
  • 36
0

The List will dynamically grow itself to accomodate as many items as you want to include - until you exceed available memory!

From MSDN documentation:

If Count already equals Capacity, the capacity of the List is increased by automatically reallocating the internal array, and the existing elements are copied to the new array before the new element is added.

If Count is less than Capacity, this method is an O(1) operation. If the capacity needs to be increased to accommodate the new element, this method becomes an O(n) operation, where n is Count.

Sapph
  • 6,118
  • 1
  • 29
  • 32
  • I get an out of memory exception when Count = 134217728 in a list of ints. got 3Gb of RAM of which 2.2 are in use. Sound normal? – Tony The Lion Jan 05 '10 at 21:37
  • Looks like you're using half a gigabyte (that many ints * 4 bytes/int32) just for that list. You're probably pushing the boundary there. Do you NEED Count to be that high? You can initialize the list without Count. – Sapph Jan 05 '10 at 21:42
  • The count just gets that high, but I can solve this another way. Thanks for all your answers though. It helped me! – Tony The Lion Jan 05 '10 at 21:45
  • Happy to help. You could also reduce the memory footprint by using a list of bytes or int16, instead of just "int". Would still be quite a bit though, and of course it'd depend on those types being suitable for your needs. – Sapph Jan 05 '10 at 21:48
0

The interface defines Count and IndexOf etc as type int so I would assume that int.MaxValue or 2,147,483,647 is the most items you could stick in a list.

Really got to question why on earth you would need that many, there is likely to be a more sensible approach to managing the data.

Paolo
  • 22,188
  • 6
  • 42
  • 49
  • 1
    I think C# and Java using 32 bit integers as index is terrible design since we had been many years in 64bits arquitecture that could easily have more than 2GB or 4GB or RAM. Ok, a list in this size is debatable, but a array as a buffer, file, streaming bigger than 2GB is just ok. And yet you will need to go off the standard library to handle a very basic issue. – Djeefther Souza Sep 23 '20 at 21:48