1

I have seen some code like this (not on consecutive lines, but in the same function scope):

Dim con1 As SqlConnection
con1 = New SqlConnection
'More code here
con1 = New SqlConnection
con1 = Nothing

I believe this is just a bug, but I wanted to check that there is not a form of shadowing going on here that I am unaware of. What happens to the first con1 variable? I assume it is inaccessible as there is no reference to the object.

4

1 に答える 1

5

ここで何が起こっているのか

con1その関数の存続期間中に2つの異なるオブジェクトを指します。

最初のオブジェクトによって作成された最初のオブジェクト

con1 = New SqlConnection

2番目以降は参照されなくなりました

con1 = New SqlConnection

実行されます。

これはメモリリークですか?

いいえ。参照されなくなったオブジェクトは最終的に破棄され、GCは破棄することを決定します。ただし、これリソースリークです。SQL接続を閉じるのに失敗するたびに(割り当てられただけでなく、開かれたと仮定して)、リソースを再利用できなくなります。GCはメモリが不足しているときにトリガーされるため、遅くともシステムのメモリが不足しているときに、参照されていないオブジェクトのメモリを確実に回復します(その時点でDB接続も回復します)。ただし、リソースが少ないとGCはトリガーされません。GCがSqlConnectionオブジェクト(それらが蓄積していたDB接続を含む)を開始して解放することを決定する前に、DB接続を完全に使い果たす可能性があります。

コードの修正

接続を解放するにはSqlConnectionを閉じる必要があるため、GCがオブジェクトを破棄することを決定するまで、最初のオブジェクトはハングします。 SQL接続は必要な期間だけ保持する必要があるリソースであるため、これは悪いことです。

新しいSqlConnectionオブジェクトを割り当てる前に最初の接続でClose()を呼び出すと、状況が改善されます(また、変数スコープを離れる前に2番目のインスタンスでClose()を呼び出します)。

ただし、コードのどこかで例外が発生した場合、適切な例外処理を行わないと、GCが起動するまで、未処理のオブジェクトが残ります。常に、このようなリソースを管理するものには常に例外処理を配置してください。

このシナリオで例外処理を実行するための最良の方法は、Usingキーワードを使用することです。私はこれまでVB.Netの行を書いたことがありませんが、これがあなたのコードの正しいバージョンでの私の試みです:

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 
于 2012-07-08T21:23:51.703 に答える