如何释放内存?

时间:2010-11-04 11:19:07

标签: vb.net entity-framework garbage-collection enumerable

我有以下循环表的方法,在每一行中更改一些值并将chages保存回数据库。为了让事情变得更快,我将以10,000行的形式获取数据。这是一张大表,里面有超过2500万条记录。

问题是我的应用程序似乎没有释放任何内存。我尝试将records变量重新声明为nothing或明确地对垃圾收集器进行调用,但内存保留在那里。 运行内置的VS10探查器我可以看到罪魁祸首是system.linq.enumerable.tolist()方法,它占用了超过98%的内存。如何在致电saveChanges后释放内存?

db = New databaseEntities
Dim size = 25000000
Dim stepSize = 10000
For i = 0 to size Step stepSize
  Dim sql = (From A In db.table).OrderBy(Function(A) A.Column).Skip(i).Take(stepSize)
  Dim records As New List(Of table)
  records = sql.ToList
  For Each record In records
    'do some work
  Next
  db.SaveChanges()
  records = Nothing
  GC.Collect()
Next

4 个答案:

答案 0 :(得分:0)

也许你可以试试这个:(我没试过它)

db.SaveChanges()
For Each record In records
    record.dispose ''only if class table got a dispose method
Next
records.clear
records = Nothing

答案 1 :(得分:0)

我绝不是Linq to SQL专家,但我的猜测是DataContext会缓存您已读取的所有行,因此您必须清空缓存或丢失对DataContext的引用。

答案 2 :(得分:0)

存储库包含对其正在跟踪的每个实体的引用,因此在存储库处于活动状态并跟踪它时,您将无法处置实体。这意味着您需要处理存储库,或者在完成处理后分离每个实体。

选项1)如果“做一些工作”不影响您返回记录的顺序,您可以在For循环中移动databaseEntities的创建,并使用using块声明它。这应该导致每次实体块都在for循环中释放

选项2)如果您的操作基本上是并行的,并且您对一个“表”实体的操作与任何其他实体没有任何依赖关系,那么您可以在db.SaveChanges之后调用databaseEntities.Detach(record),这将使垃圾收集器能够回收实体的空间。

查看您的代码,我怀疑其中任何一个都可以使用

答案 3 :(得分:0)

如果您不需要更新实体,请使用MergeOption.NoTracking。上下文将不再保留对实体的引用,也不会进行修复。