【发布时间】:2020-02-02 21:04:49
【问题描述】:
大家早上好!
我刚开始在我发现存在内存泄漏的项目中工作。
情况如下。有一个控制台应用程序基本上一直在while(true) 循环中运行。
有一堆类在循环中执行一些逻辑。 每个类都有 Execute() 方法,其中 create 使用 Task.Run() 方法,其中任何人都不会等待调用。 上述类的列表称为引擎。所有引擎都是无状态类,存储在主 Program.cs 类的数组中。
代码基本上是这样的:
private static List<BaseEngine> Engines;
public static void Main(string[] args)
{
InitializeDI();
RunProgram();
}
private static void RunProgram()
{
while (true)
{
try
{
foreach (var engine in Engines)
{
engine.Execute();
}
}
catch (Exception ex)
{
//handle
}
finally
{
Thread.Sleep(TimeSpan.FromSeconds(3));
}
}
}
private static void InitializeDI()
{
_kernel = new StandardKernel();
ServiceLocator.SetLocatorProvider(() => new NinjectServiceLocator(_kernel));
NinjectConfig.Setup(_kernel);
}
示例引擎如下所示:
public class SampleEngine : BaseEngine
{
public override void Execute(Task task)
{
var someService = ServiceLocator.Current.GetInstance<IDbContext>();
System.Threading.Tasks.Task.Run(() =>
{
// some action using dbcontext
});
}
}
在上面的 SampleEngine 示例中,它用于从 Ninject DI 获取 IDbContext。但是其他引擎可以使用在 DI 中注册的其他服务。
所有的依赖都注册为InCallScope()
基本上它就像所有引擎一样,它关于着火并且忘记了使用 Task.Run() 的给定方法。
我所做的是更改 Execute 方法以返回任务,并且在此任务运行完成后,我曾经Dispose()此任务。这没有带来任何价值。
我做了一些调查,发现问题出在Ninject.Activation.Cache 内部。我可以手动清理缓存,这会有所帮助,但我知道问题出在代码中,但我找不到。
由于每个依赖项都注册为 InCallScope(),因此它们应该在每个任务开始到结束后被释放。我没有看到任何对这些对象的引用,因为每个引擎都是无状态的。
我使用 ANTS 来查看一些信息,而且这些信息每分钟都在增长:
这指向 Ninject 缓存如下:
看起来 DbContext 没有被释放并且仍然存在于 Ninject 缓存中。是系统任务多的问题还是我做错了什么?
提前致谢 干杯!
【问题讨论】:
标签: c# multithreading ninject