我一直有各地的内存使用一些问题与LINQ到SQL。 我使用它在Windows服务,做一些处理,而我通过我从上下文中拉回来的大量数据的循环。 是的 - 我知道我可以用一个存储过程做到这一点,但是是有原因的,这将是理想的解决方案少。
反正,我所看到的主要是内存不被释放之后,即使我叫context.SubmitChanges()
所以,我最终不得不在时间做各种奇怪的事情只喜欢拉回到100条记录,或创建若干情况,并让他们都做不同的任务。 如果我保持同样DataContext
并在以后使用它对于其他调用,它只是吃了越来越多的内存。 即使我打电话Clear()
“关于var tableRows
”阵列查询将返回给我,将其设置为null,并调用SYstem.GC.Collect()
-它仍然没有释放内存。
现在,我读过一些关于你应该如何使用DataContexts
迅速,快速处置这些,但似乎他们应该是一种强制的背景下抛售其所有的数据在(或特定表的所有跟踪数据)某一点,以保证内存是免费的。
任何人都知道什么措施保证内存释放?
如果你不需要DataContext.ObjectTrackingEnabled 假目标跟踪集。 如果你需要它,你可以使用反射来调用内部DataContext.ClearCache(),但你必须知道,因为它的内部,它的主体在框架的未来版本中消失。 而据我可以告诉,框架本身并没有使用它,但它确实清除对象缓存。
一个DataContext跟踪的所有对象它曾经牵强。 直到垃圾回收也不会释放这一点。 此外,由于它实现IDisposable
,你必须调用Dispose
或使用using
语句。
这是正确的方式去:
using(DataContext myDC = new DataContext)
{
// Do stuff
} //DataContext is disposed
正如David指出的,你应该使用一个使用块处置的DataContext的。
看来,你最关心的是如何创建和处理一堆的DataContext对象。 这是LINQ2SQL是如何设计的。 在DataContext意味着寿命短。 既然你是从数据库中拉了大量的数据,这是有道理的,会有大量的内存使用情况。 你是在正确的轨道上,由大块处理您的数据。
不要害怕创建吨DataContexts的。 他们的目的是使用这种方式。
谢谢你们 - 我将签出ClearCache方法。 只是为了澄清(对于未来的读者),在我得到的内存usuage的情况是这样的:
using(DataContext context = new DataContext())
{
while(true)
{
int skipAmount = 0;
var rows = context.tables.Select(x => x.Dept == "Dept").Skip(skipAmount).Take(100);
//break out of loop when out of rows
foreach(table t in rows)
{
//make changes to t
}
context.SubmitChanges();
skipAmount += rows.Count();
rows.Clear();
rows = null;
//at this point, even though the rows have been cleared and changes have been
//submitted, the context is still holding onto a reference somewhere to the
//removed rows. So unless you create a new context, memory usuage keeps on growing
}
}
我只是碰到了类似的问题。 在我的情况下,帮助建立DataContext.ObjectTrackingEnabled的属性设置为false。 但它仅适用于通过迭代行如下的情况:
using (var db = new DataContext())
{
db.ObjectTrackingEnabled = false;
var documents = from d in db.GetTable<T>()
select d;
foreach (var doc in documents)
{
...
}
}
如果,例如,在查询中使用的方法ToArray的()或ToList() - 无影响