ここで何が起こっているのか
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