C#

C# Dispose()

program-up 2023. 11. 20. 18:15

C# 프로그램을 지금까지하면서 주구장창 사용해왔던 Dispose()...... 하지만 정확히 어떻게 동작하는지는 모르고 객체에 Dispose() 함수가 들어가 있으면 메모리관리를 위해 거의 무조건 Dispose()를 해왔었는데요.

 

Dispose()가 정확히는 몰라도 메모리를 해제해준다는건 알고 있었으니까 메모리의 누수나 가비지컬렉터가 조금이라도 덜작동하게 만들기 위해 그냥 일단 사용을 해왔고 실제로 이렇게 사용하고 나서는 특별히 메모리 관련된 문제가 나오지 않았는데요.

 

그러나 최근 만들었던 프로그램에 메모리문제인지 뭔지 원인을 알수 없는, 프로그램이 강제종료되는 상황이 생겨 골치아픈 나날을 보내고 있는데...... 메모리 문제인지 무슨 문제인지는 잘 모르겠으나 시간이 좀 있을 때, Dispose에 대해 알아보는 것이 좋을 것 같아 이번 포스팅을 남깁니다.

 

Dispose(). 마이크로소프트 문서에서는 아래와 같이 정의 하고 있습니다.

 

Microsoft 문서 이미지 출처 : https://learn.microsoft.com/ko-kr/dotnet/api/system.idisposable?view=net-6.0

 

내용은 간단하게 써져 있는데 '관리되지 않은 리소스 해제'를 위한 메커니즘을 제공합니다. 라고 나와 있습니다.

 

'관리되지 않은 리소스 해제' 즉 관리되는 리소스는 대상이 아니고 관리되지 않은 리소스를 대상으로 리소스를 해제한다는 얘기인데...... '관리되는 리소스'와 '관리되지 않은 리소스'는 무슨 차이가 있고 뭐가 다른 것일까요?

 

'관리되는 리소스'란? CLR(Common Language Runtime)의 가비지 컬렉터에 의해 관리되는 리소스로 이 리소스는 가비지 컬렉터가 알아서 리소스를 해제시켜주지만, '관리되지 않은 리소스'는 가비지 컬렉터가 리소스를 해제시켜주지 않으며 해당 리소스의 사용을 완료할 때 명시적으로 해제 해야 한다고 합니다.

 

즉, '관리되는 리소스'는 가비지 컬렉터가 알아서 리소스를 해제시켜 주고 '관리되지 않은 리소스'는 개발자가 Dispose()를 수행하여 알아서 리소스를 해제하지 않으면 메모리 누수가 발생하는 것인데, 이는 프로그램의 성능이 점차 떨어지고, 최악의 경우에는 프로그램이 비정상 종료되는 문제가 발생할 수 있습니다.

 

또한 모든 경우는 아니지만 일반적으로는 Dispose()는 '관리되지 않은 리소스'만 즉시 해제할 뿐, '관리되는 리소스'는 즉시 해제하지 않으며, 후에 가비지 컬렉터가 돌아가야 리소스가 해제되는 시스템으로 어떤 객체를 Dispose() 하였다고 하더라도 그 객체의 '관리되는 리소스'는 가비지 컬렉터가 돌아갈때 까지 남아있다는 겁니다.

 

간단한 프로그램이라면 모를까, '관리되지 않은 리소스'를 Dispose()를 해야하는게 사실상 선택이 아닌 필수사항인 것인데 그렇다면 '관리되지 않은 리소스'가 무엇이 있는지 한번 파악을 해보면... 

 

파일 핸들, 네트워크 핸들, 윈도우, 데이터 베이스의 연결, 네트워크 소켓, 그래픽 핸들, System.Runtimer.InteropServices.Marshal.AllocHGlobal메서드 등이 있으며, 이는 반드시 Dispose()또는 다른 방식의 명시적인 리소스 해제를 하셔야 합니다.

 

 

 

 

그래서 이 글의 요약 ......

Dispose() 함수가 있는 객체는 사용종료 후 Dispose() 합시다.