【发布时间】:2019-08-20 17:08:40
【问题描述】:
使用 EF Core 2.1 插入 135k 条记录。一旦请求完成,我希望上下文会被处理掉,ChangeTracking 实体也会随之被清除,但是,它会保留所有 135k 记录并在此过程中使用大量内存。
我们正在使用 ASP.NET Core 2.1 并从 DI 容器注入 EF 上下文。由于 DI 容器应该在请求结束时处理作用域上下文,它不应该保留这些值。即使在控制器末尾手动调用 dispose 似乎也不会影响更改跟踪实体。
以下是请求完成后内存使用情况的堆视图的输出。深入研究路径,我看到了很多 EF Core 类,并且奇怪地看到了不同实体的 EntityQueryable 实例(System 与 InvoicePendingItem)。
上下文正在Startup.cs中注册:
services.AddDbContext<EFContext>(options => options.UseMySql(
GetDBConnectionString()
));
【问题讨论】:
-
DBContext 注册的服务生命周期是多少?
-
你能显示将 DBContext 注册到容器的代码吗?
-
@GaryStewart,添加了它。我们使用的是默认方法,它应该是一个作用域生命周期。
-
我问的原因是堆上的对象会一直留在那里,直到它们被垃圾回收。垃圾收集是非确定性的,这意味着它在 .net 框架确定需要执行时发生。当垃圾收集发生时,堆上的对象也可能不会被释放,这取决于它们是哪一代。因此,即使请求已完成并且 DbContext 实例已被释放,这 135,000 个实例仍可能保留在堆上。您应该不看到的是通过新的
DbContext实例在不同的或新的请求上对这135,000 个实例的引用。 -
GC.Collect在没有更多引用之前不会做任何事情(因此在同一个请求中调用它没有影响,因为该请求的 DI 框架中仍然存在引用),即便如此如果对象在生成中被提升或有一个未决的终结器,则它们可以存活。
标签: c# entity-framework asp.net-core .net-core entity-framework-core