简体   繁体   English

.Net 5 IHost FileSystemWatcher memory 泄漏

[英].Net 5 IHost FileSystemWatcher memory leak

I'm currently working on a plugin-like system that requires loading in assemblies at runtime.我目前正在开发一个类似插件的系统,该系统需要在运行时加载程序集。

The root app will run as a windows service, and will create an IHost for each 'plugin' so that each one can have its own DI container.根应用程序将作为 windows 服务运行,并将为每个“插件”创建一个 IHost,以便每个插件都可以拥有自己的 DI 容器。

I started doing stress tests on it to see if there was any memory leaks when stopping/starting the 'plugins'.我开始对其进行压力测试,以查看在停止/启动“插件”时是否有任何 memory 泄漏。 Stopping/Starting involves stopping the IHost and disposing of it, then starting a new one.停止/启动涉及停止 IHost 并处理它,然后启动一个新的。 I found that there was a small memory leak somewhere.我发现某处有一个小的 memory 泄漏。 It seemed like I was gaining 10-50mb for every ~1000 restarts.似乎每重新启动 1000 次,我就会获得 10-50mb。

That's not terrible, but it made me think I wasn't disposing of something correctly.这并不可怕,但它让我觉得我没有正确处理某些东西。 I ended up finding that just starting/stopping a default IHost seemed to cause a similar issue (Though to a lesser degree).我最终发现只是启动/停止默认 IHost 似乎会导致类似的问题(尽管程度较轻)。 Below is a simple console app to show pretty much what I'm doing, and you can see it just slowly but consistently gains memory usage.下面是一个简单的控制台应用程序,几乎可以显示我在做什么,您可以看到它只是缓慢但始终如一地获得 memory 的使用。 I can see the GC is being run, so I don't think that it would ever get cleaned up.我可以看到 GC 正在运行,所以我认为它永远不会被清理。

class Program
{
    private static async Task Main(string[] args)
    {
        while (true)
        {
            var host = Host.CreateDefaultBuilder().Build();
            await host.StartAsync();

            await host.StopAsync();
            host.Dispose();
        }
    }
}

And here is the memory snapshot.这是 memory 快照。 You can see there are a few things that are consistently building up.你可以看到有一些东西在不断地积累。 The highlighted items count seems to marry up with the number of looks that have occured.突出显示的项目数量似乎与出现的外观数量相结合。

So to me, it seems like there is a file watcher being created at some point in the IHost that isn't properly being disposed.所以对我来说,似乎在 IHost 中的某个时间点创建了一个文件观察程序,但没有正确处理。 I'm guessing it might be for one of the configuration files?我猜它可能是配置文件之一?

内存快照

I added WriteLine to track the number of loops that have occured and ran it for a couple minutes.我添加了 WriteLine 来跟踪已发生的循环数并运行了几分钟。 The application starts at ~10-20mb of memory being used, but after 17000 loops it had gotten up to 200mb+.该应用程序从使用 memory 的 ~10-20mb 开始,但经过 17000 次循环后,它已达到 200mb+。 This is with the GC.Collect and GC.WaitForPendingFinalizers being called at the end of each loop.这是在每个循环结束时调用 GC.Collect 和 GC.WaitForPendingFinalizers。

循环计数的内存使用情况

My question is whether this is an issue or not.我的问题是这是否是一个问题。 Am I diagnosing this as a memory leak when it isn't?如果不是,我是否将其诊断为 memory 泄漏?

It probably wont effect me because I don't expect thousands of restarts, but is it worth creating an issue on the github if this is actually a leak?它可能不会影响我,因为我预计不会有数千次重启,但如果这实际上是泄漏,是否值得在 github 上创建问题?

EDIT:编辑:

I think I've confirmed it's a memory leak.我想我已经确认这是 memory 泄漏。 If I remove all the configuration sources by adding the following before .Build() the memory issue goes away.如果我通过在.Build()之前添加以下内容来删除所有配置源,则 memory 问题就会消失。

ConfigureAppConfiguration(config =>
{
    config.Sources.Clear();
})

Is this something I should add as an issue at https://github.com/dotnet/aspnetcore/issues ?这是我应该在https://github.com/dotnet/aspnetcore/issues添加的问题吗?

As I said in my edit, it looked to be due to the configuration setup.正如我在编辑中所说,它看起来是由于配置设置造成的。

I made an issue on the ASP Net Core Github , but it looked like someone else had already reported it a couple days prior.在 ASP Net Core Github 上提出了问题,但看起来其他人几天前已经报告过了。

Seems like David Fowler has already added pull requests to the.Net 6 preview so it should be fixed for.Net 6.似乎 David Fowler 已经在 .Net 6 预览版中添加了拉取请求,因此应该为 .Net 6 修复它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM