在以下两种情况下,如果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)序列化程序 - 负责处理这些对象,为什么不呢?
这是我已经知道了一段时间的问题,但从来没有深究过。我希望有人可以确认我找到了什么,也许可以解释是否有办法处理它。
答案 0 :(得分:3)
这实际上是您的设计问题,而不是ASP.NET。它用于通过SOAP序列化对象的XmlSerializer
对序列化的对象或它们是否实现IDisposable
一无所知。而且,即使他们做实施IDisposable
,也不会立即明白它们应该被处理掉;您可能正在返回单例实例或缓存中的对象。
Web服务应接受并返回消息类,AKA 代理类,又名Data Transfer Objects,它们是非常简单,轻量级的POCO类,没有任何实际状态或智力,特别是没有非托管资源的所有权。
您可以使用AutoMapper之类的工具快速轻松地在您的域模型类之间进行映射,例如Customer
(显然保留在数据库连接上)和Web服务使用的DTO。
答案 1 :(得分:1)
此规则可能有例外,但在大多数情况下,如果函数向您返回一个IDisposable对象,那么现在就是Dispose它的问题。
这就是你看到“泄漏”的原因。是的,GC会在需要内存时及时清理它,但在此之前,可能会有重要资源被锁定/使用。
所以请记住规则:它是IDisposable,完成后处理它!
=)