实体框架内存使用情况

5 .net c# entity-framework

在将新对象插入数据库时​​,实体框架似乎使用了过多的内存.

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();
Run Code Online (Sandbox Code Playgroud)

此时,这些对象包含的数据元素非常少.将140,000个这些对象插入数据库时​​,应用程序的总内存使用量为600 MB,而300,000的内存使用量为1.2 GB.这些对象很小,只是一个字符串名称和一个整数键.

我可以通过将SaveChanges调用放入循环来减少内存使用量,但是执行时间变得更糟,而且已经非常糟糕了.

任何人都知道实体框架为什么要使用这么多内存,或者如何让它使用更少的内存?

Aar*_*nLS 2

由于实体框架将数据保存在内存中(就像许多 ORM 一样),因此与许多内存中集合一样,可能存在内部数组。当您向集合添加项目时,内部数组的容量会加倍。

例如,如果您有一个像 ArrayList 这样包含 256 个项目的集合,并向其中添加第 257 个项目,那么内部发生的情况是为 512 个项目的数组分配一个新的内存块,并将 256 个项目的数组复制到新的内存块中。 512 项数组,然后 256 项数组可用于垃圾回收。因此,在转换点,您将在内存中分配 768 个项目,因为您添加了第 257 个项目。在使用内存流时,我遇到了令人头疼的问题,因为您需要的连续未碎片内存几乎是您真正需要的 3 倍。这是您在集合上看到的 .Capacity 属性,它几乎总是 2 的幂(因为它的大小根据需要加倍)。

我敢打赌,内部数组的大小会根据需要加倍,以支持内存对象的集合。因此,300,000 个相同类型的对象可能会保存在大小为 524,288 的内部数组中。此外,如果与 .NEt Framework 中其他地方的类似技术类似,则每当添加第 262145 个项目时,内存中都会存在 262144 和 524288 的数组,同时这些项目将被复制到新数组。内存中总共有786432项。旧数组将一直存在,直到垃圾收集器决定不再需要它为止。

实体框架中可能有一些关于并发支持的选项,您可以禁用这些选项,这可能会提高内存使用率。我只是在这里推测,但为了支持并发性,它们在内存中存储数据的当前版本和用于比较的原始版本以支持并发性。

我还会考虑过滤您正在交互的数据。尝试找到巧妙的标准来限制内存中查询和加载的内容。例如,如果您有一个应用程序允许用户编辑客户帐户,但只向他们分配了某些帐户,则将其用作过滤条件,以便仅在内存中加载用户可能与之交互的那些帐户。