メモリ管理は、特にファイル、データベース接続、または外部オブジェクトなど、手動で解放する必要のあるリソースを使用する場合、Visual Basicでオブジェクトを扱う際の重要な側面です。
従来のVB(VB6)では、リソースはSet obj = Nothingを呼び出すことによって手動で解放されていました。 .NET(VB.NET)では、未使用のオブジェクトをクリーニングする自動ガーベジコレクタが実装されています。しかし、特にアンマネージリソースに関しては、すべてのメモリ解放が自動的に行われるわけではありません。
自動ガーベジコレクタは、.NETオブジェクトのメモリを解放しますが、外部または手動リソースを適切に回収することはできません(ファイルディスクリプタ、接続、ストリーム)。これらの詳細を無視すると、メモリリークやリソースのロックが発生します。
外部リソースを適切に解放するためには、IDisposableインターフェースとUsing...End Usingステートメントを使用します。これにより、決定的な解放が保証されます。
コード例:
' ファイルディスクリプタの保証された解放 Using reader As New StreamReader("data.txt") Dim content As String = reader.ReadToEnd() ' ... データ処理 ... End Using ' IDisposableをサポートしないオブジェクトの場合、手動で解放: Dim obj As SomeComObject = New SomeComObject() ' ... 使用 ... System.Runtime.InteropServices.Marshal.ReleaseComObject(obj) obj = Nothing
重要なポイント:
FileStreamにUsingを使用しない場合、リソースはGCによって解放されますか?
いいえ、解放は不定期に行われます。ファイルのロックやリソースリークが発生する可能性があります。
Set obj = Nothingの呼び出しはDispose()の呼び出しに相当しますか?
いいえ、Set obj = Nothingは単に参照を削除するだけで、リソースが即座に解放されることを保証するものではありません。Dispose()またはUsingが、決定的な解放のための唯一の正しい方法です。
DataSet/DataTableから継承されたオブジェクトにDisposeを呼び出す必要がありますか?
はい、GCによって解放されますが、多くの関連リソース(例えば、データベース接続)は手動でDisposeまたはUsingを呼び出す必要があります。特にDataAdapter、Connection、Commandの場合は重要です。
Usingなし、Disposeなしで大きなファイルからデータを読み取ること。しばらくすると、アプリケーションが新しいファイルを開けなくなる:"File is in use by another process"。
利点:
欠点:
Usingを介してデータベースまたはファイルへの接続を開く。データを取得し、処理し、リソースを自動的に解放。
利点:
欠点: