ADO.NET 实体抛出 OutOfMemoryException。如何防止这种情况发生
SQL Server 2008 R2 中的基础表具有 int、guid 和 Filestream 列。文件流显示为 byte[]。我观察到内存消耗不断增加。我应该怎么办?
MyEntities bh = new MyEntities ();
foreach (var s in bh.TaskGraphs)
{
try
{
using (var x = new MemoryStream(s.TaskGraph1))
{
//var t = TaskGraph.Load(x);
//Validate(t);
}
}
catch (Exception e)
{
}
}
这是内存使用模式
我现在观察到执行 bh.TaskGraphs.Select(p => new { p.TaskGraph1, p.StreamId } 使异常消失,是否是由于链接到该表的子表所致
,每个 BLOB 约为 3MB ?
The underlying table has a int, guid and Filestream column in SQL Server 2008 R2. The filestream shows up as byte[]. What I observe is that the memory consumption keeps on increasing. What should I do?
MyEntities bh = new MyEntities ();
foreach (var s in bh.TaskGraphs)
{
try
{
using (var x = new MemoryStream(s.TaskGraph1))
{
//var t = TaskGraph.Load(x);
//Validate(t);
}
}
catch (Exception e)
{
}
}
Here's the memory usage pattern
I now observed that doing bh.TaskGraphs.Select(p => new { p.TaskGraph1, p.StreamId } makes the exception go away. Is it due to the child table linked to this table?
BTW, each BLOB is ~ 3MB
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
实体框架将实体加载到实体容器中,并且容器具有一个实体集,其中包含从数据库获取的实体的本地副本。每个实体都有其相应实体集的引用,整个实体集将保留在内存中,并且当您从数据库加载实体集时,实体集将不断增长。
您必须使用包含主键和其他属性的表和仅包含主键和 blob 的表之间的一对一关系将表分为两部分。
接下来,在迭代时的 for 循环中,您应该通过新的上下文加载 blob 实体并处理字节数组,并在 for 循环结束时销毁上下文。或者,您也可以从实体容器中分离对象,使其可以自由进行垃圾回收。
在现有代码中,您可以分离实体,这将释放它所持有的内存。
Entity framework loads entity in an entity container and container has an entity set which contains local copy of entity which was fetched from database. Every entity has a reference of it's corresponding entity set and entire entity set will stay in memory and entity set will be keep on growing as you will load it from database.
You must divide your table into two parts using one to one relationship with table containing primary key and other attributes and another table containing just primary key and blob.
Next in your for loop while you are iterating, you should load your blob entity via a new context and process your byte array and destroy your context at the end of for loop. Or you can also detach an object from entity container that will make it free to e garbage collection.
In your existing code you can detach your entity that will free the memory it is holding.
如果没有更多信息,很难说,但我想,以下至少是问题的一部分:
TaskGraphs
有很多行,或者Filestream
列包含一个很多日期TaskGraph.Load
和/或Validate
保留对该数据的引用,因此不会被垃圾收集。MyEntities
将Filestream
列在内存中保留一段时间,然后再将其释放。It's hard to say without more info, but I suppose, the following is at least part of the problem:
TaskGraphs
has a lot of rows or theFilestream
column contains a lot of dateTaskGraph.Load
and/orValidate
keep a reference to that data, so it will not be garbage collected.MyEntities
keeps theFilestream
columns in the memory for a certain period of time, before releasing it again.我认为 TaskGraph 表有很多记录,因此当您调用 bh.TaskGraphs 时,它将整个表加载到内存中,并且其中的二进制数据大于可用内存。
您应该尝试使用存储过程从数据库中仅加载所需的记录,因此另一种方式。
但首先尝试这个:
What i think is TaskGraph table has a lot of records, so when you call bh.TaskGraphs it loads the entire table into memory and the binary data in it bigger than memory available.
You should try to load only records you want from database by using stored procedure so another way.
but first try this:
我认为对此没有简单的解决方案。请参阅此相关问题:在实体框架中处理 BLOB流媒体时尚 4.0
I don't think there is an easy solution for this. See this related question: Handling BLOBs in Entity Framework 4.0 in a stream-fashion