Visual Basic에서 IDisposable 인터페이스(Dispose 패턴)를 구현하면 가비지 컬렉터에 의해 관리되지 않는 자원(예: 파일, 데이터베이스 연결, 그래픽 객체)을 올바르게 해제할 수 있습니다.
전형적인 구현은 다음과 같습니다:
Public Class FileManager Implements IDisposable Private fileStream As FileStream Private disposed As Boolean = False Public Sub New(path As String) fileStream = New FileStream(path, FileMode.Open) End Sub Public Sub Dispose() Implements IDisposable.Dispose Dispose(True) GC.SuppressFinalize(Me) End Sub Protected Overridable Sub Dispose(disposing As Boolean) If Not disposed Then If disposing AndAlso fileStream IsNot Nothing Then fileStream.Dispose() End If disposed = True End If End Sub Protected Overrides Sub Finalize() Dispose(False) MyBase.Finalize() End Sub End Class
중요: Using ... End Using 구문을 사용하세요 — 자동으로 Dispose가 호출되도록 보장합니다:
Using manager As New FileManager("data.txt") ' 파일 작업 End Using
주의사항:
질문: "Dispose 메서드 내에서 GC.SuppressFinalize(Me) 호출이 필요한 이유는 무엇인가요?"
정답: 이 호출은 가비지 컬렉터에게 파이널라이저(Finalizer)를 호출하지 않아도 된다고 알리며, 이미 Dispose를 통해 자원이 수동으로 해제되었음을 의미합니다. 이 호출이 없으면 파이널라이저가 불필요하게 한번 더 실행되어 성능이 저하되고 중복 해제가 발생할 수 있습니다.
이야기
은행 소프트웨어에서 IDisposable을 잘못 구현하여 데이터베이스에서 Dispose를 호출하지 않아서 연결 누수가 발생했습니다. 평균적으로 애플리케이션이 2-3일 연속으로 작업한 후 "멈추는" 현상이 발생했습니다.
이야기
의료 서비스에서 Dispose를 잘못 구현하여 (플래그 "disposed"가 없었습니다) Dispose가 여러 번 호출되어 동일한 자원을 반복적으로 해제하려는 시도로 인해 예외가 발생했습니다.
이야기
그래픽 편집기에서 GC.SuppressFinalize(Me)를 호출하는 것을 잊었습니다. Dispose 이후에도 파이널라이저가 실행되어 자원의 이중 해제가 발생하고 불안정성(access violation)이 초래되었습니다.