기본적으로 C++ 스마트 포인터는 그냥 ref count를 통해서 간단한 원리로 관리가 된다.
그리고 C#의 GC(Garbage Collection)은 루트 오브젝트에서 끊긴 포인터들을 해제시키고 살아있는 친구들은 세대를 넘겨 자주 체크 하지 않도록 한다고 알려져있다.
여기서 루트 오브젝트가 대체 뭐고 언제 연결되고 끊기는 지 궁금해져서 확인해보았다. (https://www.red-gate.com/simple-talk/development/dotnet-development/understanding-garbage-collection-in-net/)
루트 (rooted reference 라고 부르는 듯)
1. 현재 실행 중인 스레드의 지역 변수는 루트 오브젝트로 간주된다.
2. 정적 변수는 루트 오브젝트로 간주된다.
3. CPU 레지스터에 등록된 오브젝트, GC 핸들, Finalize 큐.
3. COM Interop(ex. 다른 C++ 라이브러리 사용)을 사용 시 참조 카운트 시스템을 사용하여 살아있다면 루트 오브젝트로 생각한다. (GC.KeepAlive)
루트 그래프
위에서 선정된 루트 오브젝트 목록을 순회하면서 참조 오브젝트 그래프를 만든다. 그래프가 없는 오브젝트는 해제된다.
가비지 수집 조건
메모리가 부족할때, 또는 GC.Collect 호출
메모리 압축
단편화가 엄청나게 측정 되는 경우 메모리 압축을 수행한다. C#은 메모리를 세그먼트로 나눠서 메모리를 관리하고 있고(관리되는 힙), 압축이 진행되면 오래된 쪽의 세그먼트로 이동한다.
GC 튜닝
기획 데이터나 DB 커넥션 같이 항상 살아있어야하는 데이터들은 초기화 단계에서 맨 뒷세대로 밀어버리고, FULL GC가 잘 일어나지 않도록 GC 세대별 메모리량을 조절하여 최대한 FULL GC가 일어나지 않도록 한다.
참고.
https://docs.microsoft.com/ko-kr/dotnet/standard/garbage-collection/fundamentals
'Programming > C# & Unity' 카테고리의 다른 글
C# DateTime.Now 속도 (0) | 2022.07.13 |
---|---|
C# discards (안쓰는 out var , 안쓰는 tuple 숨기기) (0) | 2022.02.08 |
C# Tuple, ValueTuple (0) | 2021.09.03 |
C# 게임 서버 (.net core) 장단점 (4) | 2021.02.15 |
C# try catch finally (0) | 2020.10.06 |