如何避免使用LINQ到SQL内存泄漏?(How do I avoid a memory leak w

2019-06-27 22:19发布

我一直有各地的内存使用一些问题与LINQ到SQL。 我使用它在Windows服务,做一些处理,而我通过我从上下文中拉回来的大量数据的循环。 是的 - 我知道我可以用一个存储过程做到这一点,但是是有原因的,这将是理想的解决方案少。

反正,我所看到的主要是内存不被释放之后,即使我叫context.SubmitChanges() 所以,我最终不得不在时间做各种奇怪的事情只喜欢拉回到100条记录,或创建若干情况,并让他们都做不同的任务。 如果我保持同样DataContext并在以后使用它对于其他调用,它只是吃了越来越多的内存。 即使我打电话Clear() “关于var tableRows ”阵列查询将返回给我,将其设置为null,并调用SYstem.GC.Collect() -它仍然没有释放内存。

现在,我读过一些关于你应该如何使用DataContexts迅速,快速处置这些,但似乎他们应该是一种强制的背景下抛售其所有的数据在(或特定表的所有跟踪数据)某一点,以保证内存是免费的。

任何人都知道什么措施保证内存释放?

Answer 1:

如果你不需要DataContext.ObjectTrackingEnabled 目标跟踪集。 如果你需要它,你可以使用反射来调用内部DataContext.ClearCache(),但你必须知道,因为它的内部,它的主体在框架的未来版本中消失。 而据我可以告诉,框架本身并没有使用它,但它确实清除对象缓存。



Answer 2:

一个DataContext跟踪的所有对象它曾经牵强。 直到垃圾回收也不会释放这一点。 此外,由于它实现IDisposable ,你必须调用Dispose或使用using语句。

这是正确的方式去:

using(DataContext myDC = new DataContext)
{
  //  Do stuff
} //DataContext is disposed


Answer 3:

正如David指出的,你应该使用一个使用块处置的DataContext的。

看来,你最关心的是如何创建和处理一堆的DataContext对象。 这是LINQ2SQL是如何设计的。 在DataContext意味着寿命短。 既然你是从数据库中拉了大量的数据,这是有道理的,会有大量的内存使用情况。 你是在正确的轨道上,由大块处理您的数据。

不要害怕创建吨DataContexts的。 他们的目的是使用这种方式。



Answer 4:

谢谢你们 - 我将签出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
   }
}


Answer 5:

我只是碰到了类似的问题。 在我的情况下,帮助建立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() - 无影响



文章来源: How do I avoid a memory leak with LINQ-To-SQL?