簡體   English   中英

不使用using()數據庫連接的后果?

[英]Consequences of not using using() DB connections?

C#中“ using”的用法很好地說明了using功能的實用程序。

.Net有其垃圾收集器。 它如何處理缺少dipose()的問題?

特別是對於數據庫連接,語句和結果集,是否需要對每個它們使用using()? 如果它們不使用using(),dispose()並且都不使用close()怎么辦?

更新:上下文是Web應用程序,因此可能有成千上萬的同時用戶,每個用戶都有自己的連接/ stmt / rs,並且該應用程序永遠不會關閉。

由於using是調用Dispose的簡寫,因此可以嘗試使用try / finally來模仿它。 因此,真正的問題是根本不調用Dispose的后果是什么。

盡管C#具有最終會在大多數時間釋放資源的垃圾回收,但是您希望關鍵資源一完成就立即釋放。 如果使用using或等效的try / finally ,資源將被快速釋放。 如果讓垃圾收集器為您釋放資源,則當程序“處於托管狀態” GC時,您的程序可能會餓死(即程序不再使用它們,但GC尚未釋放它們)。 此外,由於GC不提供運行終結器的硬保證,因此某些資源可能在程序結束之前不會明確釋放,這可能導致其他進程的資源匱乏。

您不知道何時調用並運行.net的垃圾收集器,因此它使您可以在不需要時自行進行處理。 因此,當您的代碼脫離了using()時,它將使用using()中的對象進行處置,而不是等待GC按照自己的時間表運行。

如果您不使用DB連接,則GC將根據實現的算法標准以自己的方式處理它。 掃清它可能太晚了(就計算機時鍾而言)。

垃圾收集器是一個后台線程,它不會每毫秒運行一次。 它具有特定的時間表和自己的算法,使其傾向於在特定時間工作。 例如,某些GC算法檢查沒有引用的對象,然后在GC運行時清除這些對象。

特別是對於數據庫連接,語句和結果集,是否需要對每個它們使用using()? 如果它們不使用using(),dispose()並且都不使用close()怎么辦?

實際上,內存泄漏的最壞后果是保留一些內存,直到您重新啟動PC。 但是,在這種情況下,最糟糕的后果可能是內存泄漏,直到重新啟動應用程序為止。

如果內存增長到無法再清理GC的地步,實際上,如果第二代小對象堆溢出(大對象堆也可能溢出),它將拋出內存不足異常並關閉應用程序。

.Net有其垃圾收集器。 它如何處理缺少dipose()的問題?

所有與標准數據庫連接相關的類均正確實現了Dispose和Finalize方法。 通常,這些類中有非托管資源。 非托管資源是資源(例如文件處理程序,數據庫連接處理程序等),它們可能導致更嚴重的內存泄漏,這些泄漏可能會占用內存,直到您重新啟動PC。 但是,這正是GC最終確定的地方。 如果您不為此類Disposable對象調用Dispose,則垃圾收集器將執行Finalize方法(如果存在〜destructor)並清除非托管資源。

這就是為什么需要正確實現IDispose模式並根據需要進行Dispose和Finalization的原因。 僅在具有Unanganged資源的情況下才需要完成。

無法及時Dispose數據庫對象的最可能的后果是,該程序將要求數據庫服務器代表它打開數據庫連接,並承諾將告知服務器何時不再需要它們(即關閉它們),但是不再需要連接后,可能會使其保持打開狀態一段時間。 這種行為可能會增加數據庫服務器需要同時保持打開狀態的連接數。 取決於服務器,可能沒有結果,或者額外的連接可能會影響性能,或者可能導致某些連接請求被不必要地拒絕。

盡管.NET會嘗試確保在放棄數據庫對象時將通知數據庫服務器,即使不調用Dispose ,使用數據庫對象的代碼通常也會知道何時不再需要它們,而.NET可以確定他們被遺棄了。 還要注意,盡管某些與.NET數據庫相關的庫可能在Dispose之后使連接保持打開狀態一會兒(以便如果代碼再次需要該數據庫,它可以使用較早的連接來恢復運行),但這些庫可以使用計時器來限制連接的時間保持其預期用途,而不是依賴垃圾收集器(垃圾收集器可能會花費很長時間而沒有注意到對象已被丟棄)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM