3

考虑具有连接池内存泄漏问题(例如连接未正确关闭)的ASP.NET应用程序。IIS应用程序池和.NET垃圾回收

回收应用程序池是否清除连接池(从而允许建立更多连接)?

如果连接留在内存中,直到垃圾收集器删除它们,这是否在应用程序池重新启动时发生(或者它们是否可以超出该范围)?我也明白垃圾收集器可以在任何时候清理它们,但它们是否仍在使用中,直到重置或应用程序池重新启动才能收集?

我在审查一个系统,其中最终目标显然是要纠正代码以正确管理连接,并且我正试图获得对垃圾收集/应用程序池过程的更多理解。

回答

5

是的,回收应用程序池杀死并重新启动负责运行您的应用程序的IIS进程。现在所有的资源都被释放,只是因为这个过程正在退出。

如果进程从未重新启动并且只是泄漏句柄,垃圾回收器将最终清理它们。但是,在这种情况发生之前,您可能会耗尽处理任何资源泄漏的情况。这就是为什么在这些对象上调用Dispose()很重要(最好是通过“using”模式),以便在应用程序完成后尽快释放资源,而不是在垃圾回收器接近它时释放资源。

1

连接池是数据库连接的缓存。应用程序池是一个(或多个)工作进程。因此,当关闭应用程序池时,您将关闭工作进程并启动新的工作进程;这将导致池被销毁,连接池中的所有连接都将关闭。

如果您没有在连接上调用Close或Dispose并依赖垃圾回收器,那么连接可能会返回到池中,也可能不会返回到池中。我认为只有当连接仍然有效并且达到最大池大小时才会将其添加回池中。正如你可能知道的,你永远不应该依赖垃圾收集器。确保连接的简单方法是Disposed是使用using语句,它将在代码块的末尾自动调用Dispose。

在ADO.NET 2.0中有以编程方式管理池的新方法:ClearAllPools和ClearPool。这可能会帮助您解决问题,直到您可以修复所有数据访问代码。

+0

幸运的我,我不会是一个不得不做的修复!真正的问题是在应用程序中过度使用datareaders ...没有try/catch/finally块,所以如果在处理代码从不运行并且连接用完时发生错误... – davidsleeps 2009-07-20 11:19:17