当(de)序列化一次性对象时,ASP.NET Web服务会泄漏内存吗?

时间:2010-04-26 03:11:40

标签: web-services memory-leaks asmx idisposable

在以下两种情况下,如果Customer是一次性的(实现IDisposable),我相信它不会被ASP.NET处理,可能是内存泄漏的原因:

    [WebMethod]
    public Customer FetchCustomer(int id)
    {
        return new Customer(id);
    }

    [WebMethod]
    public void SaveCustomer(Customer value)
    {
      // save it
    }

此(涉嫌)缺陷适用于任何IDisposable对象。例如,从ASP.NET Web服务返回DataSet也会导致内存泄漏 - 不会丢弃DataSet [编辑:This post声称Dispose on DataSet什么都不做,所以也许这不是这样的问题]

在我的情况下,客户打开了一个在Dispose中清理的数据库连接 - 除了从未调用Dispose导致加载未关闭的数据库连接。我意识到这里有一大堆不好的做法,但重点是ASP.NET - (de)序列化程序 - 负责处理这些对象,为什么不呢?

这是我已经知道了一段时间的问题,但从来没有深究过。我希望有人可以确认我找到了什么,也许可以解释是否有办法处理它。

2 个答案:

答案 0 :(得分:3)

这实际上是您的设计问题,而不是ASP.NET。它用于通过SOAP序列化对象的XmlSerializer对序列化的对象或它们是否实现IDisposable一无所知。而且,即使他们实施IDisposable,也不会立即明白它们应该被处理掉;您可能正在返回单例实例或缓存中的对象。

Web服务应接受并返回消息类,AKA 代理类,又名Data Transfer Objects,它们是非常简单,轻量级的POCO类,没有任何实际状态或智力,特别是没有非托管资源的所有权。

您可以使用AutoMapper之类的工具快速轻松地在您的域模型类之间进行映射,例如Customer(显然保留在数据库连接上)和Web服务使用的DTO。

答案 1 :(得分:1)

此规则可能有例外,但在大多数情况下,如果函数向您返回一个IDisposable对象,那么现在就是Dispose它的问题。

这就是你看到“泄漏”的原因。是的,GC会在需要内存时及时清理它,但在此之前,可能会有重要资源被锁定/使用。

所以请记住规则:它是IDisposable,完成后处理它!

=)