asp.net核心自托管应用在Webhost重生时泄漏

时间:2019-01-22 08:27:06

标签: c# asp.net-core memory-leaks

我有一个自托管的asp.net核心应用,需要偶尔使用新的上下文重新生成其WebHost。 App在asp.net DI容器中将共享资源注册为单例。

            services.AddSingleton<MyDep>();

控制器取决于共享资源:

[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
    public MyDep Dep { get; }

    public ValuesController(MyDep dep)
    {
        Dep = dep;
    }

    // GET api/values
    [HttpGet]
    public ActionResult<IEnumerable<string>> Get()
    {
        return new string[] {
            new string(Dep.Content),
            "value2" };
    }
 }

它泄漏绑定到前一个实例的资源。我使用演示应用程序(稍微修改了asp.net核心api项目模板)重现了该问题。

public static void Main(string[] args)
    {
        var p = new Program();
        while (true)
        {
            p.Boot(args);
            GC.Collect(2, GCCollectionMode.Forced, true);
        }
    }

    private void Boot(string[] args)
    {
        webHost = CreateWebHostBuilder(args).Build();
        webHost.RunAsync();
        Thread.Sleep(5000);
        webHost.StopAsync().Wait();
        webHost.Dispose();
    }

我看到了n个控制器实例,其中n是对控制器的http请求数-控制器根本没有被处置。 事件探查器在链的末尾使用System.Threading.OverlappedData指示到root的长路径。您能否建议此设置有什么问题? sample app

path to root

2 个答案:

答案 0 :(得分:1)

  

我看到了n个控制器实例,其中n是对控制器的http请求数

这是预期的行为。默认情况下,将为每个请求创建控制器。

your snapshot中,我看不到有多个MyDep实例。快照显示了Func<ValueController, MyDep>的实例,该实例不是预期的单例。如果调用委托,您将在不同请求中获得MyDep的相同实例。一般来说,这里没有错。您正在寻找错误的类型。

答案 1 :(得分:0)

好的,我为所描述的问题显示了错误的踪迹。但是,上下文尚未正确释放。

我找到了一个解决方案:IApplicationLifecycle.StopApplication,如此处所述-> https://www.blakepell.com/asp-net-core-ability-to-restart-your-site-programatically-updated-for-2-0

上下文已正确释放,内存占用也不再无限增长