我们的ASP .NET应用程序遇到了巨大的内存泄漏。它使用EF 6和Castle Windsor。在应用程序运行了几个小时后,我们可以很容易地看到物理内存稳定地爬升,看不到尽头。在应用程序开始超时之前,应用程序重启是我们唯一的救星。
从下图中可以看出,内存由自定义数据库上下文占用。
The screenshot shows the memory usage by the custom DB Context
我认为问题在于控制器的注册。除了注册为LifestyleTransient的控制器外,IoC中的所有内容都注册为LifestylePerWebRequest。如果我尝试将控制器注册为LifestylePerWebRequest,我会收到如下错误。我认为容器正在坚持所有这些实例,而不知道何时让它们离开。
控制器'Acme.Web.Controllers.HomeController'的单个实例不能用于处理多个请求。如果正在使用自定义控制器工厂,请确保为每个请求创建一个新的控制器实例。
如何解决这个问题,以便将DB Context与层次结构的其余部分一起清理?
答案 0 :(得分:2)
我想我找到了答案。我之前遇到过WindsorControllerFactory,但我还没有使用它。现在它已就位并如下所示注册,容器正在释放控制器。现在它被释放了,它被拿起来进行垃圾收集。到目前为止,它似乎运作良好。
var controllerFactory = new WindsorControllerFactory(container.Kernel);
ControllerBuilder.Current.SetControllerFactory(controllerFactory);
答案 1 :(得分:1)
虽然你可以这样做:
_container.Kernel.ReleasePolicy = new NoTrackingReleasePolicy();
我认为一种更好的方法,除非你在所有层中使用相同的上下文,IoC注入一个DbContextFactory,并且在存储库中,你将在工厂的Create()调用周围创建一个using语句。然后你可以在完成后杀死dbcontext,而不是让容器处理它。你甚至可以让工厂挂起第一个上下文,如果你真的需要并且处理dbcontextfactory,你可以在内部dbcontext上调用dispose。