6

我有一个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[]fromSystem.Web.Caching或的实例占用System.Runtime.Caching,但是与我在 IIS 工作进程上获得的内存增加相比,这些完全没有。

我的问题是,IIS 是故意这样做的吗?也许这是为连接线程分配的,以防万一以后需要它们?这是 IIS、ASP.NET 或 MVC 4 的错误吗?

我决定为此使用 MVC 4 的 WebAPI 功能,因为我们希望它灵活、可维护、面向未来并且可以通过 AJAX 访问。从开发的角度来看,这似乎也很有意义,因为我们也在 MVC 4 中构建了网站。

然而,一位同事现在将此作为系统架构的一个关键问题提出,因为我们(将来)将需要连接数千个客户端。他建议我们改用 WCF。那么,额外的问题 - 使用 WCF 会解决这些问题吗?

4

2 回答 2

1

MS 现场工程师有一篇关于这个主题的精彩文章。可能会有帮助。

于 2013-02-27T15:25:35.997 回答
0

经过更多的试验和测试,不幸的是,我发现这是无法避免的。这似乎是设计使然,或者是 IIS 的一个真正根深蒂固的问题。

我改变了我的方法以使用一个较低级别的选项:实现一个IHttpAsyncHandler来做同样的事情。我为 MVC 使用了一个自定义 HttpHandler 路由,以允许我使用与以前使用的完全相同的 URL。问题仍然存在,但规模略小。

然后我尝试了一个完全空白IHttpHandler的简单返回{ ready: false }(就像我的代码在超时时所做的那样)。HttpHandler 中没有包含其他代码,但同样的问题仍然存在。

接下来,我尝试了一个完全空白的 WCF 服务,该服务也返回了{ ready: false }. 同样的问题,但这次规模更小。

正如链接@rusev的回答所暗示的那样:

内存碎片和其他自然降级无法避免,回收确保应用程序定期清理。

这可能是问题的原因。我可以想象,因为在使用 MVC 控制器时会有更多的开销,所以碎片会发生得更快。使用 HttpHandler 或 WCF 服务等较低级别的方法会在每个连接中使用更少的内存,因此会导致更少的碎片。

于 2013-03-01T16:22:09.623 回答