.net - 是什么导致我的 Entity Framework Core dbContext 泄漏内存?
问题描述
这涉及到 Microsoft.EntityFrameworkCore.SqlServer,特别是 2.1.14 版本
我在我的服务层中使用 EF,该服务的 API 之一是用于批量操作。所有上下文相关的代码都使用构造函数注入。连接字符串确实启用了 MARS。我像这样注册我的数据库上下文:
services.AddDbContext<ServiceAvailabilityContext>(options => options.UseSqlServer(saConnection));
我已确保所有调用代码都作为 Scoped Task 执行运行。我有一个批处理过程,它同时执行 50 个任务操作,总共 500 个,并且会尝试定期运行 500 个。但是,我注意到随着时间的推移,该服务的堆大小内存消耗只会越来越大。我已经在我的开发机器上运行批处理器和服务的三个演出,并且还尝试运行服务运行时构建。 每个服务命令或查询都在 IMediatR IRequestHandler 中运行,为了确保它们被作为 Scoped 调用,我添加了如下管道行为:
var response = await Task.Run(async () =>
{
using (var scope = _serviceScopeFactory.CreateScope())
{
return await next();
}
});
调用栈基本上是 Controller -> MediatR Request Handler(context constructor injection) -> Operation。
似乎 EF 只是将所有类型的集合保存在内存中,并且出于某种原因没有释放它们,即使原始上下文已经超出范围,并且所有其他引用也超出了范围。我没有返回 IQueryables,每次检索数据时,我都会立即执行 .ToList() 或 .FirstorDefault() 来完成语句。我什至从未在模型中返回实体对象本身,而是将它们类型转换为 UI 友好对象。我也尝试调用一个方法来打断点,并手动调用 GC.Collect() 没有释放任何内存!
我的主要问题是……为什么?我错过了什么?
解决方案
事实证明,即使 DbContext 与 DI 作用域一起使用,幕后的 ChangeTracker 仍保留对象 HashSet。在不修改对象或分离对象时,我必须更改我的检索语句以使用 AsNoTracking(),而我在调用 SaveChanges() 之后确实对其进行了更改,这消除了内存问题。
推荐阅读
- firebase - 了解 index.js firebase 函数中的部署目标
- xml - 字符串连接functoid不将映射值返回到目标记录
- ios - 在 ios 中从不同的视图控制器(不是同时)多次调用相同的 Web 服务
- python - 将值应用于列并按这些值对所有列进行分组
- python - 需要帮助:Python 文件路径
- java - 带有 Picocli 的 CLI:在调用子命令之前调用主命令
- python - 将网页中的抓取标题写入熊猫框架
- php - 如何将 textarea 值作为单独的变量获取?
- android - 忽略起始空格和特殊字符仅大写字符串中的第一个字母
- c++ - 选择的回溯值