【发布时间】:2015-12-08 16:00:43
【问题描述】:
在我的测试中,我正在逐行读取文本文件并插入一个实体以及其他相关实体。问题是当插入太多时,我会收到内存不足异常。
为了防止这种情况,我为每 50 行创建一个新的 DbContext 并处理旧的 DbContext。我的理解是,这会从早期的实体操作中释放内存,但内存会继续攀升,如果文件足够大,则会发生内存不足异常。这与实体代码有关,好像我删除了添加实体的代码行,内存保持一致。
以下是我的代码的简化版本。
public class TestClass
{
public void ImportData(byte[] fileBytes)
{
using (Stream stream = new MemoryStream(fileBytes))
{
TextFieldParser parser = new TextFieldParser(stream);
parser.TextFieldType = FieldType.Delimited;
parser.SetDelimiters(",");
while (!parser.EndOfData)
{
//Processes 50 lines creates a new DbContext each time its called
ImportBatch(parser);
}
}
}
public void ImportBatch(TextFieldParser parser)
{
using(myDbContext context = new myDbContext())
{
context.Configuration.AutoDetectChangesEnabled = false;
int batchCount = 0;
while (!parser.EndOfData && batchCount < 50)
{
string[] fields = parser.ReadFields();
//Here I call some code that will add an entity and add releated entities
//In its navigation properties
MyService.AddMyEntity(fields,myDbContext);
batchCount++;
}
myDbContext.ChangeTracker.DetectChanges();
myDbContext.SaveChanges();
}
}
}
当我每 50 次插入处理和创建一个新上下文时,我希望内存使用量保持不变,但前 2000 行似乎是不变的,但之后内存不断攀升,单位是 OutOfMemory 异常打。
是否有理由说明以下列方式处理 dbContext 不会导致内存被释放?
编辑 - 添加了我的添加实体方法的一些简化代码
public void AddMyEntity(string[] fields, MyDbContext, myDbContext)
{
MyEntity myEntity = new MyEntity();
newRequest.InsertDate = DateTime.UtcNow;
newRequest.AmendDate = DateTime.UtcNow;
//If I remove this line the memory does not consistently climb
myDbContext.MyEntities.Add(myEntity);
foreach(string item in fields)
{
ReleatedEntity releatedEntity = new ReleatedEntity();
releatedEntity.Value = item;
newRequest.ReleatedEntities.Add(releatedEntity);
}
}
另一个编辑
经过更多测试后发现它与 Glimpse 分析器有关。我在我的项目中包含了 Glimpse,并且 web 配置有一个类似于下面的部分。
<glimpse defaultRuntimePolicy="On" endpointBaseUri="~/Glimpse.axd">
<tabs>
<ignoredTypes>
<add type="Glimpse.Mvc.Tab.ModelBinding, Glimpse.Mvc5"/>
<add type="Glimpse.Mvc.Tab.Metadata, Glimpse.Mvc5"/>
</ignoredTypes>
</tabs>
<inspectors>
<ignoredTypes>
<add type="Glimpse.Mvc.Inspector.ModelBinderInspector, Glimpse.Mvc5"/>
</ignoredTypes>
</inspectors>
将 defaultRuntimePolicy 设为 Off 可修复内存泄漏。还是不知道为什么
【问题讨论】:
-
你不是一直在添加前50个字段吗?
-
@GregoryHouseMD 你的权利,我的错误,将编辑。无论哪种方式,这只是演示我的问题的简化代码
-
仅仅因为你正在处理一个对象并不意味着它正在被垃圾收集。您正在运行 Visual Studio 2015 吗?如果没有,请获取社区版并在运行探查器的情况下进行调试。您将看到垃圾收集活动。如果您没有看到任何垃圾收集,那么您可能需要在 ImportBatch 方法结束时进行一些手动垃圾收集。
-
可能
MyService.AddMyEntity泄漏内存。能把这个方法的代码也贴一下吗?
标签: c# asp.net entity-framework memory glimpse