Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

.net collections memory optimization - will this method work?

Just like almost any other big .NET application, my current C# project contains many .net collections .
Sometimes I don't know, from the beginning, what the size of a Collection (List/ObservableCollection/Dictionary/etc.) is going to be.
But there are many times when I do know what it is going to be.

I often get an OutOfMemoryException and I've been told it can happen not only because process size limits, but also because of fragmentation.

So my question is this - will setting collection's size (using the capacity argument in the constructor) every time I know its expected size help me prevent at least some of the fragmentation problems ?

This quote is from the msdn :

If the size of the collection can be estimated, specifying the initial capacity eliminates the need to perform a number of resizing operations while adding elements to the List.

But still, I don't want to start changing big parts of my code for something that might not be the real problem.

Has it ever helped any of you to solve out of memory problems ?

like image 748
programmer Avatar asked Jan 29 '11 11:01

programmer


People also ask

How does .NET manage memory?

Memory allocation NET framework that allocates and releases memory for your . NET applications. When a new process is started, the runtime reserves a region of address space for the process called the managed heap. Objects are allocated in the heap contiguously one after another.

How does memory allocation work in C#?

The Common Language Runtime (CLR) manages allocation and deallocation of a managed object in memory. C# programmers never do this directly, there is no delete keyword in the C# language. It relies on the garbage collector.

What are the types of memories supported in the .NET framework?

There are two types of memory allocation: stack memory and heap memory.


2 Answers

Specifying an initial size will rarely if ever get rid of an OutOfMemory issue - unless your collection size is millions of object in which case you should really not keep such a collection.

Resizing a collection involves defining a completely new array with a new additional size and then copying the memory. If you are already close to out of memory, yes, this can cause an out of memory since the new array cannot be allocated.

However, 99 out of 100, you have a memory leak in your app and collection resizing issues is only a symptom of it.

like image 111
Aliostad Avatar answered Oct 03 '22 10:10

Aliostad


If you are hitting OOM, then you may be being overly aggressive with the data, but to answer the question:

Yes, this may help some - as if it has to keep growing the collections by doubling, it could end up allocating and copying twice as much memory for the underlying array (or more precicely, for the earlier smaller copies that are discarded). Most of these intermediate arrays will be collected promptly, but when they get big you are using the "large object heap", which is harder to compact.

Starting with the correct size prevents all the intermediate copies of the array.

However, it also depends what is in the array matters. Typically, for classes, there is more data in each object (plus overheads for references etc) - meaning the list is not necessarily the biggest culprit for memory use; you might be burning up most of the memory on objects.

Note that x64 will allow more overall space, but arrays are limited to 2GB - and if each reference doubles in size this halves the maximum effective length of the array.

Personally I would look at breaking the huge sets into smaller chains of lists; jagged lists, for example.

like image 40
Marc Gravell Avatar answered Oct 03 '22 09:10

Marc Gravell