개발이야기/C#

[C#]IDisposable, Finalize, using 이 무엇인가? 그리고 왜 사용하는가?

Kim_Jack 2022. 10. 1. 20:59
반응형

IDisposable, Finalize, using 이 무엇인가? 그리고 왜 사용하는가? 

 

C#의 가비지 컬렉터는 사용이 끝난 메모리를 자동적으로 해지시켜준다.

하지만 가바지 컬렉터가 인식하지 못하는 메모리의 종류가 있다. 관리되지 않는 리소스라고 칭하는데

파일스트림 객체나, 창 핸들, 디비 커넥션과 같은 객체들이다.

이러한 객체들을 해지 시켜주기 위해서

Finalize, IDisposable, using 과 같은 기능들이 있는데 하나씩 설명해보겠다.

 

 

Finalize

Finalize는 소멸자와 비슷한 개념이라고 생각하면 된다.

클래스에서 소멸자를 만들면 이는 Finalize를 오버라이딩한거와 같다.

그래서 관리되지 않는 리소스들을 소멸자에서 해지시켜주는 것 또한 하나의 방법이다.

하지만 이는 몇가지 문제점들을 야기한다.

 

소멸자(Finalize)를 구현하면 이 객체는 메모리가 바로 해지되지않고,

컴파일시에 finalization queue에 해당 객체가 등록되고 가비지 컬렉터가 작동할때 해당 객체의 소멸자를 호출한다.

사용하지 않는 메모리를 가비지 컬렉터가 수집해갈때까지 붙잡고 있는게 무척 비효율적이다.

그리고 혹여나 바로 지워지지 않는다면 해당 메모리는 1세대 2세대 까지 올라가게 될 가능성 또한 존재한다.(1세대 2세대가 무슨말인지 모르겠다면 세대별 가비지컬렉터에 대해 공부하기)

그래서 Finalize를 사용하기 보다는 IDisposable를 사용하는걸 권장한다.

 

 

IDisposable

IDisposable은 Dispose함수가 선언되어있는 인터페이스이며 이를 상속받은 클래스에서는 Dispose함수를 구현해야한다.

여기서 궁금한 점은 Dispose함수를 구현해서 그안에서 리소스를 해지시키라는것은 알겠는데,

그게 다른 일반 함수내에서 해지시켜 호출하는거랑 뭐가 다르냐? 이거다

즉, 왜 굳이 Dispose를 써야해? 인데

이는 using 과 관련이 있다.

특정 리소스 혹은 객체를 사용할때 using으로 만들어 사용하는걸 본 적이 있을 것이다.

using (StreamReader sr = new StreamReader(filename))
{
     txt = sr.ReadToEnd();
}

using으로 감싸진 저 객체는 using 구문이 끝내면 내부적으로 클래스에 구현되어있는 dispose함수를 실행시킨다.

그래서 using을 사용하기 위해 우리는 IDisposable를 사용하는 것이다.

 

IDisposable을 상속하지 않는다면 using 구문 사용시 에러를 뿜는다.

 

IDisposable, finalize, using은 서로 이러한 관계가 있다. 

 

세 줄 요약

finalize를 사용하기엔 효율이 무척 구리고

using을 쓰면 코드도 깔끔하고 메모리가 바로 해지되기에 효율도 좋다

그리고 그 using을 사용하기 위해선 IDisposable을 상속받아 Dispose를 구현해야한다!  

반응형