Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# : Out of Memory exception

Today my application threw an OutOfMemoryException. To me this was always almost impossible since I have 4GB RAM and a lot of virtual memory too. The error happened when I tried to add an existing collection to a new list.

List<Vehicle> vList = new List<Vehicle>(selectedVehicles);  

To my understanding there isn't much memory allocated here since the vehicles my new list should contain already exist inside the memory. I have to admit Vehicle is a very complex class and I tried to add about 50.000 items to the new list at once. But since all Vehicles in the application come from a database that is only 200MB in size, I have no idea what may cause an OutOfMemoryException at this point.

like image 888
TalkingCode Avatar asked Dec 19 '11 15:12

TalkingCode


Video Answer


4 Answers

3 years old topic, but I found another working solution. If you're sure you have enough free memory, running 64 bit OS and still getting exceptions, go to Project properties -> Build tab and be sure to set x64 as a Platform target.

enter image description here

like image 158
a'' Avatar answered Oct 16 '22 21:10

a''


Two points:

  1. If you are running a 32 bit Windows, you won't have all the 4GB accessible, only 2GB.
  2. Don't forget that the underlying implementation of List is an array. If your memory is heavily fragmented, there may not be enough contiguous space to allocate your List, even though in total you have plenty of free memory.
like image 22
Tudor Avatar answered Oct 16 '22 21:10

Tudor


.Net4.5 does not have a 2GB limitation for objects any more. Add this lines to App.config

<runtime>
    <gcAllowVeryLargeObjects enabled="true" />    
</runtime>

and it will be possible to create very large objects without getting OutOfMemoryException

Please note it will work only on x64 OS's!

like image 76
Lendmann Avatar answered Oct 16 '22 20:10

Lendmann


Data stored in database compared to memory in your application is very different.

There isn't a way to get the exact size of your object but you could do this:

GC.GetTotalMemory() 

After a certain amount of objects have been loaded and see how much your memory is changing as you load the list.

If it is the list that is causing the excessive memory usage then we can look at ways to minimize it. Such as why do you want 50,000 objects loaded into memory all at once in the first place. Wouldn't it be best to call the DB as you require them?

If you take a look here: http://www.dotnetperls.com/array-memory you will also see that objects in .NET are greater than their actual data. A generic list is even more of a memory hog than an array. If you have a generic list inside your object then it will grow even faster.

like image 15
Adam Avatar answered Oct 16 '22 19:10

Adam