c# - 实体框架 - 是否可以在不同的 AppDomain 之间共享存储在内存中的 DbCompiledModel 和元数据信息?
问题描述
我们有一个基于 ERP 的大型应用程序,在几个不同的项目中使用了多种 .net 技术。解决方案结构类似于:
类库:
- 核心(基础设施、扩展、实用程序等)
- 业务(与到 Gentle.Net 的映射紧密耦合的 POCO)是一个将被重构为 Web 服务的遗留层。
- 域(从数据库反映的 poco 对象,为 EF 创建)
- 数据(EF dbcontext,将配置映射到域对象)
- InstanceContext = 所有表的数据库上下文(约 400 个映射表)
- ReadOnlyContext = 所有数据库视图的 db 上下文(约 500 个映射视图)
网页服务:
- Web 服务(旧版 asmx 服务)
- API(网络 API)
前端:
- WebForms 应用程序(90% 的前端)
- WebForms 应用程序在旧 cas 模式下停留在 .net 3.5 上,以允许本地 rdlc 报告的良好导出性能。
- MVC 应用程序(这里是较新的前端开发)
- 根据客户需求定制的各种 WinForms 智能客户端应用程序
我们正在逐步重构应用程序,希望能够解耦一些业务逻辑例程。我们首先用 Entity Framework 替换 Gentle.Net ORM(一个非常古老的 ORM,多年来一直很好地对待我们)。但是,我们遇到了内存利用率问题(不是内存泄漏)。
起初看起来很轻松,因为我们针对现有数据库运行了 EF 反向 POCO 生成器,并实现了 DbConfiguration 功能来生成 EDMX 文件(以加快启动时间)。
现在大多数前端和 Web 服务项目都在使用 EF,内存需求猛增。每个 AppDomain 需要约 500MB 的内存来保存数据库上下文,这发生在 EF 初始化期间。我们已经完成了广泛的内存分析,并且可以确认我们的上下文使用被正确处理。似乎 DbCompiledModels 永远保留在内存中,因为 EF 需要缓存的数据才能运行。
我可以将 MVC/Webforms、ASMX/WebAPI 项目合并在一起以减少所需的内存,因为这将消除 2 个 AppDomain。但我想知道是否有一种方法可以在不同的 AppDomain 之间共享缓存的实体模型\映射信息。像分布式缓存,但对于 DbCompiledModels?
每个项目在 IIS 中作为单个网站下的应用程序运行,并且它们将始终使用相同的数据库上下文\映射,因此它们不一定需要每个 AppDomain 实例化。
*注意——虽然有更好的方法来重构这个问题,但由于应用程序的大小,它们需要大量的时间来重构和测试。修复低悬的果实会给我们一些喘息的空间。如果每个应用程序可以在启动时共享实体框架所需的内存映射信息,那将减少 50% 的内存利用率。
解决方案
每个 AppDomain 需要约 500MB 的内存来保存数据库上下文,这发生在 EF 初始化期间。
我建议您可能持有 DbContext 太久?或者您的数据库结构非常庞大。可以随心所欲地使用和处置 DbContext,因此使您的方法调用尽可能小 - 并记住将 DbContexts 注册为作用域,以便充分处置它们
推荐阅读
- python - Word 表中的文本
- python - 使用 for 循环在 pandas 中附加多个数据帧
- php - 表列的两个内部连接到不同的表
- php - 将主题应用于 Yii2 高级应用程序
- apache-spark - 在 Clojure Flambo api 调用中进行 DataFrame 查找时无法获得结果
- javascript - 不能用“null”覆盖背景色
- php - 在输入字段中隐藏 html 值
- three.js - 填充边界问题,具有堆叠透明纹理的 360 场景中的低 fps
- java - 如何将参数添加到 Spring Batch 项目阅读器?
- python - AttributeError: 'REST' 对象没有属性 'get_bars' (Alpaca trade API + Tensorflow)