简体   繁体   中英

Entity framework memory usage

The entity framework appears to use excessive amounts of memory when inserting new objects into a database.

for(int i = 0; i < numOwners; ++i)
{
    var owner = Owner.CreateOwner();
    db.AddToOwnerSet(owner);
    for(int j = 0; j < numChildren; ++j)
    {
        var child = Child.CreateChild();
        owner.Childs.Add(child);
    }
}
db.SaveChanges();

At this point, these objects are contain very few data element. When inserting 140,000 of these objects into the database, total memory usage of the application was 600 MB, and 1.2 gigabytes for 300,000. These objects are small, just a string name and an integer key.

I can reduce the memory usage by putting SaveChanges calls into the loop, but then execution time gets much worse, and it is already pretty bad.

Anyone know why the entity framework is using so much memory, or how to get it to use less memory?

I know this is an old question but I was experiencing the same problem today and managed to find out what was causing it!

It would appear that the generation of the SQL scripts is responsible for the large jump in memory. I found that creating stored procedures and linking them to my objects (but make sure that you return the value for the ids as shown in this article ) saved me more than 300mb of memory.

Since the entity framework keeps data in memory(as do many ORM's), then as with many in-memory collections there are probably internal arrays. As you add items to a collection, the internal array doubles in capacity.

For example, if you have a collection like an ArrayList containing 256 items, and add the 257th item to it, then what happens internally is a new block of memory is allocated for a 512 item array, they 256 item array is copied to the new 512 item array, and then the 256 item array is made available for garbage collection. Thus at the point of transition you will have 768 items allocated in memory just because you added the 257th item. I have run into headaches with this when using memorystream, because you need almost 3 times as much contigous unfragmented memory than what you really need. This is the.Capacity property you see on collections, and it is almost always a power of 2(since it double in size as needed).

My bet is there are internal arrays that double in size as needed to support your collections of in memory objects. So 300,000 objects of the same type would probably be held in an internal array of size 524,288. Additionally, if it's like similar techniques elsewhere in the.NEt Framework, then whenever the 262145th item was added, both an array of 262144 and 524288 existed in memory while the items were copied to the new array. A total of 786432 items in memory. The old array would stick around until the garbage collector decided it wasn't needed anymore.

There might be some options in the Entity framework regarding concurrency support that you could disable which might improve memory usage. I am only speculating here though, but to support concurrency they store in-memory both the current version of the data, and it's original version for comparison to support concurrency.

I would also look at filtering what data you are interacting with. Try to find clever criteria to limit what is queried and loaded in memory. For example, if you had an application that allowed a user to edit customer accounts, but only certain accounts were assigned to them, then use that as your filtering criteria so that you only load in memory those accounts that the user could potentially interact with.

Your objects might be "small" in terms of actual data, but each object isn't a DTO - the Entity Framework attaches a lot of boilerplate code to each of your entities, meaning the actual size of each object is quite large.

If you are consistently working with large object graphs, consider using something like NHibernate which is stable, mature and proven to work. The Entity Framework is very far behind in terms of features and performance.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM