使用TopShelf和Automapper C#的Windows服务内存泄漏

我正在使用TopShelf(基于C#.NET 4.6.1中的控制台应用程序)运行Windows服务,并且正在使用Automapper 9.0.0。我每隔10秒运行一个任务,该任务处理一个Ms SQL数据库(使用实体框架)中的约1000行,似乎Automapper占用了大量内存,并且每次任务运行时内存都会增加(在任务管理器中,可以看到该服务占用了超过3000 Meg的RAM ++。

我是Automapper的新手,现在不需要任何代码来手动释放内存。在某个地方,我看到了大量的处理程序,我想知道Automapper是否生成这些处理程序,以及如何清理它们。

我尝试在每个任务的末尾放置一个 GC.Collect(),但似乎没有什么不同

使用TopShelf和Automapper C#的Windows服务内存泄漏

这是我的任务的代码摘录:

private void _LiveDataTimer_Elapsed(object sender,ElapsedEventArgs e)
        {
            // setting up Ninject data injection
            var kernel = new StandardKernel();
            kernel.Load(Assembly.GetExecutingAssembly());
            //var stationExtesions = kernel.Get<IStationExtensionRepository>();
            //var ops = kernel.Get<IOPRepository>();
            //var opExtensions = kernel.Get<IOPExtensionRepository>();
            //var periods = kernel.Get<IPeriodRepository>();
            //var periodExtensions = kernel.Get<IPeriodExtensionRepository>();


            // create the LiveDataTasks object
            //var liveDataTasks = new LiveDataTasks(stationExtesions,ops,opExtensions,periods,periodExtensions);

            // sync the station live data
            //liveDataTasks.SyncLiveStationData();

            // force garbage collection to prevent memory leaks
            //GC.Collect();

            Console.WriteLine("LiveDataTimer: Total available memory before collection: {0:N0}",System.GC.GetTotalMemory(false));
            System.GC.Collect();
            Console.WriteLine("LiveDataTimer: Total available memory collection: {0:N0}",System.GC.GetTotalMemory(true));
        }

MOFICATIONS:我在显示使用的TotalMemory的代码的末尾添加了一些控制台输出。我删除了GC.Collect(),因为它没有任何改变,并注释掉了大多数访问数据库的代码。现在我意识到kernel.Load(Assembly.GetExecutingAssembly());已经使内存增长非常快。请参见以下控制台捕获:

使用TopShelf和Automapper C#的Windows服务内存泄漏

现在,如果我注释掉kernel.Load(Assembly.GetExecutingAssembly());,我将再次获得稳定的记忆状态。我如何处置或卸载内核???

使用TopShelf和Automapper C#的Windows服务内存泄漏

ly122653002 回答:使用TopShelf和Automapper C#的Windows服务内存泄漏

好吧,首先,您不应该在服务中执行数据库工作。将数据库数据上的任何大操作移出数据库只会增加必须通过网络两次将数据移至数据库中的操作(一次移至客户端程序,一次移回数据库),同时还面临着竞争状况和许多其他问题的风险。我的长期建议是:始终保持数据库在数据库中工作。

至于内存占用量,这种变化只是对已用内存的误读:

.NET使用垃圾收集内存管理方法。其结果是,在任何给定应用程序的GC进行收集的同时,所有其他线程必须暂停。结果,GC在运行时非常懒惰。如果它仅在应用程序关闭时运行一次-这是理想的情况。因此,它尝试避免不必要地运行。在向您抛出OutOfMemoryException之前,它仍将尽可能地运行。但除此之外,只需要不断分配越来越多的对象而无需清理就很高兴。

您可以通过调用GC.Collect()来测试它是否是。但是,这样的调用通常不应使用生产代码。另一种GC策略(尤其是用于WebServer的GC策略)可能会更好。

,

我终于弄清楚了发生了什么:用于设置 NInject数据注入 kernel.Load(...)增加了我的记忆力:

var kernel = new StandardKernel();
kernel.Load(Assembly.GetExecutingAssembly());

因此,我将这段代码从每x秒执行一次的函数移到了父类的构造函数中,该类在初始化时只执行一次。

这解决了问题。

感谢大家的启发和帮助!!!!

本文链接:https://www.f2er.com/3103392.html

大家都在问