CLR 어떻게 메모리에 객체를 할당하는가?

 

넓은 메모리 공간을 통째로 확보해서 하나의 관리되는 힙 (Managed Heap)을

마련한다. 그리고 CLR은 이렇게 확보한 관리되는 힙의 첫 번째 주소에

"다음 객체를 할당할 메모리의 포인터"를 위치 시킨다.

object A = new object();

 



CLR이 코드를 실행하면 "다음 객체를 할당할 메모리의 포인터"가

가리키고 있는 주소에 A객체를 할당하고 포인터를 A 객체가

차지하고 있는 공간 바로 뒤로 이동시킨다.

 

CLR은 객체가 위치할 메모리를 할당하기

위해 메모리 공간을 쪼개 만든 연결 리스트를 탐색하는 시간과

재조정하는 작업도 필요하지 않다. 그저 메모리만 할당할 뿐

 

if (true){

object a = new object();

}


 

a를 잃은 채 힙에 남아 있는 객체 A는 이제 코드의 어디에서도

접근할 수 없기 때문에 더 이상 사용할 수 없게 되었다.

즉 쓰레기가 되고, 가비지 컬렉터가 집어가게 된다.

 

[C#] 가비지 컬렉터 (Garbage Collector) 의 원리, 동작 메커니즘

 

사라져버린 a처럼 할당된 메모리의 위치를 참조하는 객채를 일컬어

루트(Root)라고 부른다. 루트는 a의 경우처럼 스택에 생성될 수도 있고

정적 필드처럼 힙에 생성될 수도 있다. .NET 에플리케이션이 실행되면

jit 컴파일러가 이 루트들을 목록으로 만들고, CLR은 이 루트 목록을

관리하며 상태를 갱신한다. 이 루트가 중요한 이유는 가비지 컬렉터가

CLR이 관리하고 있던 루트 목록을 참조해서 쓰레기를 수집하기 때문.


1. 작업을 시작하기 전에, 가비지 컬렉터는 모든 객체가 쓰레기라고 가정.

루트 목록 내의 어떤 루트도 메모리를 가리키지 않는다고 가정.

 

2. 루트 목록을 순회하면서 각 루트가 참조하고 있는 힙 객체와의

관계 여부를 조사. 루트가 참조하고 있는 힙의 객체가 또 다른 힙 객체를

참조하고 있다면 이 역시도 해당 루트와 관계가 있는 것으로 판단.

어떤 루트와도 관계가 없다면 쓰레기로 간주.

 

3. 쓰레기 객체가 차지하고 있던 메모리는 이제 '비어있는 공간'

 

4. 루트 목록에 대한 조사가 끝나면, 가비지 컬렉터는 이제 힙을

순회하면서 쓰레기가 차지하고 있던 '비어있는 공간'에 쓰레기의

인접 객체들을 이동시켜 차곡차곡 채워 넣는다.

 

가비지컬렉션의 단점

 1 메모리를 언제 되찾을지 결정하기 위한 오버헤드가 수반된다 이로인해 더 느리게 작동하는 경우가 있다. 

 2. 시스템에서 메모리를 너무 많이 할당하고 프로그래머가 직접 관리하지 못 하므로 알맞은 시점에 메모리를 비우지 못하는 일도 발생할 수 있다.

 

가비지 컬렉션의 메커니즘을 바탕으로 효율적인 코드를 작성하기 위한 방법

  • 객체를 너무 많이 할당하지 마세요.
  • 너무 큰 객체 할당을 피하세요.
  • 너무 복잡한 참조 관계는 만들지 마세요.
  • 루트를 너무 많이 만들지 마세요.

 


'C#, ASP.NET, CORE, MVC' 카테고리의 다른 글

[C#] 기초문제1  (0) 2018.07.19
[C#] 상수 선언, const 와 readonly  (0) 2018.07.19
5강. 클래스 OOP  (1) 2018.07.19
4강. 파일 입출력  (0) 2018.07.19
3강. 배열  (2) 2018.07.19

+ Recent posts