5장 - 5

2014. 12. 2. 23:59IT Books/시작하세요 C# 프로그래밍

가비지 수집기

(Gabage Collector)


CLR의 힙은 세대(generation)를 나눠 관리.



이런식으로 진행.
가비지 수집이 될때마다 살아있는 객체는 1세대가 승격되며
최대 2세대까지 승격.
이후에는 2세개 메모리 공간의 크기만 계속 늘어나게 된다.

이 예제에서 지역변수에 명시적으로 null을 대입하지 않는 이상 객체는 유효.

특이한 점은
가비지 수집이 일어날때마다 살아남은 객체는  GC에 의해 메모리 정렬이 일어나므로
힙의 주소가 바뀔 수 있다는 사실이다.

--
가비지 수집으로 인해 큰 용량을 가진 객체가 이동된다면 성능 손실이 있을 수 있으므로.
CLR은 일정 크기 이상의 객체는 Large Object Heap : LOH라는 특별한 힙에 할당한다.

LOH에 할당된 객체는 가비지 수집 이후에도 주소가 변경되지 않는다.
따라서 LOH안의 객체들이 할당 / 해제를 하다보면 필연적으로 메모리 단편화가 생긴다.
LOH 객체는 처음부터 2세대에 해당한다.

--
자원 해제
MS에서는 자원해제가 필요하다 판단되는 모든 객체는 
IDisposable 인터페이스를 상속하게끔 권하고 있다.




멤버를 딱 하나 가졌다.

자원 해제를 명시해야 하는 코드라면 
인터페이스를 통한 약속을 기억하자.

다만 Dispose 호출전에 예외가 발생한다면?
당연히 Dispose 호출이 안되기 때문에
IDisposable을 구현하는 객체는 
대개 try / finally를 이용해 Dispose를 호출하는 게 관례이다.


다만 이런 구현은 번거롭기 때문에

using을 이용하여 간편하게 할 수 있다.

using예약어는 try / finally > Dispose의 단순 표기에 해당한다.



--

소멸자

GC가 동작할 때 호출되는 것이 보장됨.


1. 소멸자가 구현된 객체를 생성하면 GC가 종료 큐(finalization queue)라는 내부 자료구조에 등록한다.

2. 이 객체는 참조되는 루트 객체가 없어졌더라도 소멸자가 있기 때문에 바로 힙에서 제거하지 않고 별도의 Freachable 큐에 객체를

다시 보관한다.

3. 이 큐에 있는 객체의 소멸자는 CLR이 미리 생성해 둔 스레드가 호출하는데 이제서야 힙에 있던 객체가 소멸가능한 상태가 되고

4. 이후 다시 GC가 동작하면 힙에서 제거된다.


이런 복잡한 과정을 GC가 부담하기 때문에

특별한 이유가 없다면 소멸자를 추가하지 않는 것을 권장한다.


다만 개발자가 미리 Dispose()를 호출했다면 굳이 위의 과정을 거칠 필요가 없다.

때문에 GC.SuppressFinalize 를 호출하면 종료 큐에서 제거된다.



'IT Books > 시작하세요 C# 프로그래밍' 카테고리의 다른 글

6장 - BCL - 2  (0) 2014.12.08
6장 - BCL - 1  (0) 2014.12.07
5장 - 4  (0) 2014.11.27
5장 - 3  (0) 2014.11.24
5장 - 2  (0) 2014.11.23