我見過這樣的(不連續線,但在相同的功能範圍內)的一些代碼:.NET功能範圍陰影
Dim con1 As SqlConnection
con1 = New SqlConnection
'More code here
con1 = New SqlConnection
con1 = Nothing
我相信這僅僅是一個錯誤,但我想檢查這裏沒有一種形式的陰影,我不知道。第一個con1
變量會發生什麼變化?我認爲它是無法訪問的,因爲沒有提及對象。
我見過這樣的(不連續線,但在相同的功能範圍內)的一些代碼:.NET功能範圍陰影
Dim con1 As SqlConnection
con1 = New SqlConnection
'More code here
con1 = New SqlConnection
con1 = Nothing
我相信這僅僅是一個錯誤,但我想檢查這裏沒有一種形式的陰影,我不知道。第一個con1
變量會發生什麼變化?我認爲它是無法訪問的,因爲沒有提及對象。
該函數的生命週期內這裏發生了什麼
con1
指向兩個不同的對象。第二
con1 = New SqlConnection
執行後
第一個目的,由第一
con1 = New SqlConnection
創建不再被引用。
這是內存泄漏嗎?
號是不再被引用最終將被安置的對象,則GC決定這樣做。但它是資源泄漏。每次關閉SQL連接失敗時(假設它已打開並且不僅僅分配了),則會使資源無法再使用。 GC將觸發時內存低,所以你肯定會在最近收復未引用的對象內存當系統內存不足(也將重新獲得在該點的數據庫連接)。然而,低資源將不是觸發GC。在GC決定啓動並釋放SqlConnection對象(包括它們囤積的數據庫連接)之前,您可以完全從數據庫連接運行。
修復代碼
由於SqlConnection的必須關閉,以釋放連接,直到GC決定出售它的第一個對象會流連。 這是一件壞事,因爲SQL連接是一種只能根據需要保留的資源。
調用指定新SqlConnection對象將改善情況之前關閉()第一個連接(也,調用Close()在二審離開變量的作用域之前)。但是,如果你在代碼的某個地方得到一個異常,如果沒有適當的異常處理,你仍然會留下未配置的對象,直到GC開始運行。總是要把異常處理放在任何管理資源的東西上,比如這個。
把異常處理到位對於這種情況最好的方法是使用Using關鍵字。我從來沒有寫過一行VB。網到現在爲止,但這裏是我在正確的版本代碼的嘗試:
Dim con1 As SqlConnection
Using con1
con1 = New SqlConnection
End Using
'More code here
Using con1
con1 = New SqlConnection
End Using
' NOTE: I believe the following is unnecessary, but was necessary in VB6 and prior
' con1 = Nothing
不,在VB6中從來沒有必要(除非你有一個循環參考的情況,在這種情況下是的,你必須手動打破鏈)。 – GSerg 2012-07-08 21:32:39
實際上'SqlConnection'的構造函數什麼都不會導致內存泄漏(所有數據庫的東西都在'Connection.Open'中完成)。 http://stackoverflow.com/a/8408475/284240 – 2012-07-08 21:37:59
@TimSchmelter:當然,但這似乎是相當合理的,「這裏更多的代碼」實際上會對連接做些什麼:-) – 2012-07-08 21:39:43
它的重新分配,因此無法再訪問 - 現在的參考點在一個SqlConnection的新實例。這可能是一件壞事,特別是當連接打開的時候,因爲直到對象被[非確定性地]處置時它纔會被關閉。請(請!)始終考慮在Using語句中包裝SqlConnection,SqlCommand等的實例 - 請參閱http://msdn.microsoft.com/en-us/library/htd05whh(v=vs.80).aspx – dash 2012-07-08 21:21:45
只有一個變量。 – 2012-07-08 21:21:58
對我來說這是一個錯誤。 SqlConnection應該用Close/Dispose或'using'語句來處理。確實垃圾收集器會處理丟失的處理,但是如果在非常嚴格的循環中調用此代碼會發生什麼? – Steve 2012-07-08 21:27:40