.NET Framework中使用Microsoft.Extensions.DependencyInjection引发内存泄漏
问题分析与修复方案
内存泄漏的核心原因是自定义DependencyResolver没有正确处理服务Scope的释放逻辑:
- 在
BeginScope方法中,你调用serviceProvider.CreateScope()创建了IServiceScope,但仅保留了它的ServiceProvider属性,没有持有IServiceScope实例本身。而IServiceScope是IDisposable类型,只有调用其Dispose方法,才会触发该Scope内所有Transient实例(包括你的Controller)的释放。 - 当前的
Dispose方法是空实现,完全没有执行Scope的清理操作,导致所有在Scope中创建的对象被ServiceProvider持续持有,无法被垃圾回收器回收。
具体修复步骤
1. 修改DependencyResolver,持有并正确释放IServiceScope
public class MicrosoftDefaultDependencyResolver : System.Web.Mvc.IDependencyResolver , System.Web.Http.Dependencies.IDependencyResolver { private readonly IServiceProvider _serviceProvider; private readonly IServiceScope _scope; // 根Resolver构造(无Scope) public MicrosoftDefaultDependencyResolver(IServiceProvider serviceProvider) { _serviceProvider = serviceProvider; _scope = null; } // 子Scope的Resolver构造,直接持有Scope实例 private MicrosoftDefaultDependencyResolver(IServiceScope scope) { _scope = scope; _serviceProvider = scope.ServiceProvider; } public IDependencyScope BeginScope() { return new MicrosoftDefaultDependencyResolver(_serviceProvider.CreateScope()); } public void Dispose() { // 释放Scope,自动清理该Scope内的所有Transient对象 _scope?.Dispose(); } public object GetService(Type serviceType) { return _serviceProvider.GetService(serviceType); } public IEnumerable<object> GetServices(Type serviceType) { return _serviceProvider.GetServices(serviceType); } }
2. 补充Web API的Resolver配置
你的Resolver同时实现了MVC和Web API的接口,但当前Startup仅设置了MVC的Resolver,需要额外添加Web API的配置,避免Web API请求的Scope未被正确处理:
public void Configuration(IAppBuilder app) { var resolver = GetDependencyResolver(); // 设置MVC依赖解析器 DependencyResolver.SetResolver(resolver); // 设置Web API依赖解析器 GlobalConfiguration.Configuration.DependencyResolver = resolver; app.MapAzureSignalR(GetType().FullName); GlobalHost.TraceManager.Switch.Level = SourceLevels.Error; }
额外注意事项
- 确保控制器的所有依赖也注册为合适的生命周期(Transient或Scoped),避免因依赖对象被长期持有导致的间接内存泄漏。
- 无需更换到Autofac等其他IoC框架,修复当前Resolver的Scope释放逻辑即可解决内存问题。
内容的提问来源于stack exchange,提问作者Daniel Kidd
相关产品推荐
相关产品推荐

