C# 공부

[C#] 가비지 컬렉터 (Garbage Collector)

ogh4554 2025. 4. 11. 23:41

1. 개념

: C#, JAVA와 같은 Managed Language에 존재하며 더 이상 사용하지 않는 객체, 데이터를 자동으로 탐지하고 메모리에서 제거해주는 시스템. C#에서 GC는 .NET 프레임워크의 일부로, 개발자가 메모리 관리에 신경을 덜 쓰도록 도움.힙 영역에서 동작.


2. 동작원리

- Mark And Sweep 알고리즘을 사용하여 동작.

 

1) 마킹(Marking)

: GC는 루트 오브젝트로부터 시작하여 모든 접근가능한 객체들을 마킹합니다.

* 루트 오브젝트 - 정적변수(Static), 스택영역의 변수, CPU 레지스터

 

2) 스위핑(Sweeping)

: 마킹되지 않은 객체들을 힙에서 제거하여 메모리를 회수

 

3) 컴펙션(Compaction)

: 남아있는 객체들을 힙의 시작부분으로 이동시켜 메모리 단편화를 줄임

* 메모리 단편화 - 메모리에 빈공간은 많지만 필요한 크기만큼의 연속적인 공간이 없어서 할당이 실패하거나 비효율적으로 되는 현상

 

+ 가비지 컬렉션은 세대 기반으로 동작.

0세대 : 가장 최근에 할당된 객체들이 위치.

1세대 : 0세대에서 살아남은 객체들이 이동하여 위치.

2세대 : 1세대에서 살아남은 객체들이 이동하여 위치

LOH(Large Object Heap) : 크기가 85,000바이트를 초과하는 큰 객체는 0세대가 아닌 바로 LOH에 할당.

-> 대용량 객체가 자주 할당되고 해제되는 것을 막아 메모리 단편화를 줄이고, 성능을 향상시키기 위함

-> 빈도가 낮지만 GC 비용이 큼


3. 가비지 컬렉션 과정

1) 객체 할당

: 새로운 객체는 0세대에 할당. 0세대가 가득차면 가비지 컬렉션이 발생

2) 0세대 가비지 컬렉션(Minor GC)

: 0세대에서 살아남은 객체들은 1세대로 이동. 0세대 GC는 빠르고 자주 발생.

3) 1세대 가비지 컬렉션

: 1세대도 가득차면 가비지 컬렉션 발생. 1세대에서 살아남은 객체들은 2세대로 이동.

4) 2세대 가비지 컬렉션(Major GC)

: 2세대도 가득차면 가비지 컬렉션 발생. 드물게 발생하지만 가장 큰 비용.

     2세대에서 살아남은 객체들은 계속 2세대에 남음.

5) Full GC

: 가장 강력하고 비용이 많이 드는 프로세스. 모든 힙영역을 대상으로 수행.

=> 일반적으로 메모리가 부족하거나, 명시적으로 호출되었을 때 발생.


4. *가비지 컬렉션을 줄이기 위한 방법*

1) 객체 재사용

: 빈번하게 생성/파괴 되는 객체를 재사용. Ex) 오브젝트 풀링

2) 구조체 사용

: 값 타입(Struct)를 활용하여 힙 할당을 줄임. 값 타입은 스택에 저장되므로 힙을 사용하지 않음.

3) 큰객체 관리

: 큰 객체는 LOH에 할당되므로, 사용을 최소화하고 분할하여 사용.

4) 불필요한 할당 피하기

: 임시 객체의 생성을 최소화 하고, 필요한 경우 명시적으로 메모리를 해제

=> Update문에서 new 키워드 사용하지 말자!!

5) String 연산도 조심. Ex) 문자열 합치기

=> StringBuilder를 사용하자

6) LINQ 남용을 하지 말기