You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET Framework中使用Microsoft.Extensions.DependencyInjection引发内存泄漏

问题分析与修复方案

内存泄漏的核心原因是自定义DependencyResolver没有正确处理服务Scope的释放逻辑:

  1. 在BeginScope方法中,你调用serviceProvider.CreateScope()创建了IServiceScope,但仅保留了它的ServiceProvider属性,没有持有IServiceScope实例本身。而IServiceScope是IDisposable类型,只有调用其Dispose方法,才会触发该Scope内所有Transient实例(包括你的Controller)的释放。
  2. 当前的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 03:06:24