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