我设置了AsyncController
来执行长轮询操作。这一切都运行正常,但是一位同事注意到服务器上的内存泄漏似乎随着每个新连接而增加。
我已经创建了一个小应用程序,可以从这个页面请求数千次,我正在监视IIS进程的内存使用情况。每个连接都会增加内存使用量,但在客户端断开连接时不会一直下降。
经过进一步调查后,我发现即使我用标准AsyncController
替换我的Controller
,但仍然会发生这种情况,除此之外什么都不做:
public class WaitController : Controller
{
public JsonResult Member(string oauth_token, int service_id, bool busy = false)
{
return Json(new
{
ready = false,
}, JsonRequestBehavior.AllowGet);
}
}
虽然在这方面没有那么多内存使用情况,但行为似乎完全相同。
我已经运行了一个内存分析器来显示10,000个连接之间的区别,那里几乎没有任何东西。大多数内存由来自ExpiresEntry[]
或System.Web.Caching
的{{1}}实例占用,但与我在IIS工作进程中获得的内存增加相比,这些内存总数为空。
我的问题是,IIS是否按设计进行此操作?也许这已被分配给连接线程,这些线程只是在以后需要它们时才会被挂起?这是IIS,ASP.NET还是MVC 4的错误?
我决定使用MVC 4的WebAPI功能,因为我们希望它具有灵活性,可维护性,面向未来并可通过AJAX访问。从开发的角度来看,它似乎也有意义,因为我们也在MVC 4中构建了网站。
然而,一位同事现在将此作为系统架构的一个关键问题提出,因为我们将来(将来)需要连接数千个客户端。他建议我们改用WCF。所以,奖金问题 - 将使用WCF解决这些问题吗?
答案 0 :(得分:2)
MS现场工程师对此主题有一个很棒的article。可能会有所帮助。
答案 1 :(得分:0)
经过更多的实验和测试,遗憾的是,我发现这一点无法预防。它似乎是设计或IIS的真正根深蒂固的问题。
我改变了我的方法以使用更低级别的选项:实现IHttpAsyncHandler
来做同样的事情。我使用custom HttpHandler route for MVC允许我使用与之前使用的完全相同的网址。这个问题仍然存在,但规模略小。
然后我尝试了一个完全空白的IHttpHandler
,只返回{ ready: false }
(因为我的代码会在超时时执行)。 HttpHandler中没有包含其他代码,但仍然会出现同样的问题。
接下来,我尝试了一个完全空白的WCF服务,该服务也返回{ ready: false }
。同样的问题,但这次的规模甚至更小。
正如链接@rusev的回答所示:
无法避免内存碎片和其他自然降级,并且回收可确保定期清理应用程序。
这可能是问题的原因。我可以想象,因为使用MVC控制器时会有更多的开销,所以碎片发生得更快。使用较低级别的方法(如HttpHandler或WCF服务)将为每个连接使用更少的内存,因此可以减少碎片。