ASP.NET Web 服务在(反)序列化一次性对象时泄漏内存?

发布于 2024-08-30 14:23:22 字数 733 浏览 1 评论 0原文

在以下两种情况下,如果 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 将不会被释放 [编辑:这篇文章声称数据集上的 Dispose 不执行任何操作,所以也许这不是一个问题]

在我的例子中,客户打开了一个已清理的数据库连接在 Dispose 中 - 除非从未调用 Dispose,从而导致未关闭的数据库连接负载。我意识到这里遵循了一大堆不好的做法,但重点是 ASP.NET(反序列化器)负责处理这些对象,那么为什么不呢?

这是我很久以前就意识到的一个问题,但一直没有深入了解。我希望有人能证实我的发现,也许还能解释是否有办法处理它。

In the following two cases, if Customer is disposable (implementing IDisposable), I believe it will not be disposed by ASP.NET, potentially being the cause of a memory leak:

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

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

This (alleged) flaw applies to any IDisposable object. So returning a DataSet from a ASP.NET web service, for example, will also result in a memory leak - the DataSet will not be disposed [EDIT: This post claims that Dispose on a DataSet does nothing, so maybe this isn't such a problem]

In my case, Customer opened a database connection which was cleaned up in Dispose - except Dispose was never called resulting in loads of unclosed database connections. I realise there a whole bunch of bad practices being followed here, but the point is that ASP.NET - the (de)serializer - is responsible for disposing these objects, so why doesn't it?

This is an issue I was aware of for a while, but never got to the bottom of. I'm hoping somebody can confirm what I have found, and perhaps explain if there is a way of dealing with it.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

黑凤梨 2024-09-06 14:23:22

这实际上是您的设计问题,而不是 ASP.NET 的问题。它用于通过 SOAP 序列化对象的 XmlSerializer 不知道有关被序列化的对象的任何信息,也不知道它们是否实现 IDisposable。此外,即使它们确实实现了IDisposable,但它们是否应该被处置并不是立即显而易见的;您可能会返回一个单例实例,或者缓存中的一个对象。

Web 服务应该接受并返回消息类,又名代理类,又名数据传输对象,它们是非常简单、轻量级的 POCO 类,没有任何真实状态或智能,尤其是没有非托管资源的所有权。

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

This is really a problem with your design, not with ASP.NET. The XmlSerializer it uses to serialize objects over SOAP doesn't know anything about the objects being serialized or whether or not they implement IDisposable. Moreover, it's not immediately apparent that they should be disposed, even if they do implement IDisposable; you might be returning a singleton instance, or an object in the cache.

Web services should accept and return message classes, AKA proxy classes, aka Data Transfer Objects, which are very simple, lightweight POCO classes without any real state or intelligence and especially no ownership of unmanaged resources.

You can use a tool like AutoMapper to quickly and easily map between your domain model classes like Customer (which apparently holds onto a database connection) and the DTOs that your web service uses.

甜味超标? 2024-09-06 14:23:22

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

这就是您看到“泄漏”的原因。是的,当需要内存时,GC 会及时清理它,但在此之前,潜在的重要资源仍处于锁定/使用中。

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

=)

There might be exceptions to this rule, but in most cases, if a function returns an IDisposable object to you, it's now your problem to Dispose it.

That's why you're seeing the "leak". Yes, in time the GC will clean it up when memory is needed, but until it does, potentially important resources remain locked/in-use.

So remember the rule: It's it's IDisposable, Dispose of it when done!

=)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文