ASP.NET网站内存使用率相当高如何解决?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (78)

我有一个ASP.NET网站,它会在大约3-4天内使用大约2GB的物理内存,这对我来说听起来非常糟糕。目前,我已配置IIS重启应用程序池过程,当它达到500MB。我想尝试跟踪这个问题。

在.NET中创建对象的新实例时,我的印象是它不需要被释放,因为.NET垃圾回收器会为我执行此操作。

是这种情况,还是这可能是我有问题的原因之一?

提问于
用户回答回答于

.NET将非常有效地为你管理垃圾收集。虽然在实现IDisposable它的类型中明智地称这种Dispose方法,但这可能不是你的问题。内存泄漏可能在.NET中发生,原因很多。这里有几个:

  • 在会话中缓存每个用户的太多数据。
  • 在应用程序缓存中的应用程序级别或静态变量(如字典)中缓存太多数据。
  • 可以在会话或应用程序级别存储网页控件(或用户控件)。
  • 将实例挂接到静态类型的事件或保持被引用的类型(因为它们存储在缓存中)。

我希望这给你一些关于在哪里看的想法。

你应该看这个关于ASP.NET调试的视频

关于你对我的回答的评论如下。CLR将收集所有托管内存,因此创建的所有对象都new将被收集。在这个意义上,一个对象是否实现并不重要IDisposable或不。然而,很多时候需要直接或间接使用本地资源(如文件句柄,图形句柄,数据库连接,使用native -thus非托管内存)。CLR不知道如何释放这些资源。对于这个.NET有终结者的概念。终结器是一个类的开发人员可以实现的虚拟方法。当你这样做时,CLR将在该类型的实例未被引用并且被收集之前调用该方法。终结器通常包含释放这些资源的逻辑。换句话说,当一个类型需要本地资源时,它通常会有一个允许类型释放这些资源的终结器方法。

关于CLR,关于这个故事在这里结束。CLR没有具体处理实现IDisposable接口的对象。但是,.NET垃圾收集器本质上是不确定的。这意味着你不知道它何时运行以及它是否运行。这意味着可能需要很长时间才能清理原生资源(因为终结器只能在收集后才能被调用)。然而,对于许多资源,只要你完成了它们,就有必要发布它们。例如,当不关闭它们或者当通过System.Drawing命名空间在.NET中使用GDI +时,倾向于快速耗尽数据库连接。

出于这个原因IDisposable介绍了界面。同样,CLR和垃圾收集器也不会看这个接口。它是类型与其用户之间的契约,允许其用户直接释放对象的底层资源。在正常的设计中,对象的终结器和对象的Dispose方法都会调用相同的私有或受保护的方法来释放这些资源。当一个类型实现时,在完成它时IDisposable将其称为Dispose方法是明智的,或者将该对象包装在using语句中以允许本地资源的释放是确定性的。

所以回到你的问题。所有托管对象都将由GC收集,但本地资源不会。因此类型可能会实现一个终结器方法,这些对象通常也会实现这个IDisposable接口。调用Dispose它们将显式并直接释放这些本地资源。

用户回答回答于

高内存使用量可能有很多原因,但.NET中的垃圾收集是一件非常精确的事情。也就是说,它对你有很大的帮助,但有时候并不像你期望的那么好。

具体来说,它只能清理没有活动引用的对象,所以如果你完成了一个类,但仍然有一个引用它,你会想要删除该引用,以便GC可以恢复该内存为你。另外,如果你有任何不活动的开放连接(比如说,对数据库或其他东西),不要忘记关闭并处理它们。通常,我们将这些对象封装在如下using块中:

using(SqlConnection conn = new SqlConnection(myConnString))
{ ...rest of code here }

这将自动关闭并处理连接; 我很确定它也让你免费试用/最后。

扫码关注云+社区

领取腾讯云代金券