我有一个包含超过20M条记录的DbContext,需要转换为不同的数据格式。因此,我将数据读入内存,执行一些任务,然后释放DbContext。代码可以正常运行,但是过一段时间后,我会收到OutOfMemoryExceptions错误。我已经能够缩小问题范围,发现以下代码片段:首先检索2M条记录,然后释放它们并再次获取。第一次检索工作正常,第二次检索会抛出异常。
// first call runs fine
using (var dbContext = new CustomDbContext())
{
var list = dbContext.Items.Take(2000000).ToArray();
foreach (var item in list)
{
// perform conversion tasks...
item.Converted = true;
}
}
// second call throws exception
using (var dbContext = new CustomDbContext())
{
var list = dbContext.Items.Take(2000000).ToArray();
foreach (var item in list)
{
// perform conversion tasks...
item.Converted = true;
}
}
GC难道不应该自动释放在第一个using语句块中分配的所有内存,使得第二个语句块的运行与第一个一样顺畅吗?
在我的实际代码中,我并不是一次检索200万条记录,而是在每次迭代中检索0到30K条左右。然而,在大约15分钟后,我会耗尽内存,尽管所有对象都应该已被释放。
list
应该像您发布的那样是本地的。此外,您使用的using
块将自动处理DbContext的释放,而不是列表,如果list
不像您在此处发布的那样是本地的,则可能会出现问题。 - Hopeless