Golang의 가비지 컬렉터 이해
James Reed
Infrastructure Engineer · Leapcell

Key Takeaways
- Go의 가비지 컬렉터는 성능 최적화를 위해 동시성, 비세대성, 비압축성을 가집니다.
- 효율적인 메모리 관리를 위해 mark-and-sweep 알고리즘과 3색 추상화를 사용합니다.
- 쓰기 장벽은 동시 실행 중 메모리 무결성을 유지하는 데 도움이 됩니다.
일반적으로 Golang으로 알려진 Go 프로그래밍 언어는 가비지 컬렉터(GC)로 알려진 자동 메모리 관리 시스템을 통합합니다. GC의 주요 기능은 프로그램에서 더 이상 사용하지 않는 메모리를 식별하고 회수하여 메모리 누수를 방지하고 사용 가능한 메모리 리소스를 최적화하는 것입니다.
Go 가비지 컬렉터의 설계 원칙
Go의 GC는 세 가지 주요 설계 원칙으로 특징지어집니다.
-
비세대성: 수명(예: young 또는 old generations)에 따라 객체를 분류하는 일부 언어와 달리 Go는 이러한 구별 없이 모든 객체를 균일하게 처리합니다.
-
비압축성: 가비지 컬렉션 프로세스 중에 Go의 GC는 메모리에서 객체를 재배치하지 않습니다. 이 접근 방식은 객체를 이동하고 참조를 업데이트하는 데 따른 오버헤드를 방지합니다.
-
동시성: Go의 GC는 애플리케이션 코드와 동시에 작동하여 가비지 컬렉션이 수행되는 동안 프로그램이 계속 실행될 수 있도록 하여 일시 중지 시간을 최소화합니다.
이러한 설계 선택은 tcmalloc
을 기반으로 하는 Go의 메모리 할당 전략의 영향을 받습니다. 이 할당자는 메모리 조각화를 효과적으로 관리하여 객체 압축의 필요성을 줄입니다. 또한 Go의 컴파일러는 이스케이프 분석을 사용하여 변수를 스택에 할당할 수 있는지 여부를 결정하여 메모리 관리를 더욱 최적화합니다.
Mark-and-Sweep 알고리즘
Go의 GC는 가비지 컬렉션의 일반적인 기술인 mark-and-sweep 알고리즘을 활용합니다. 이 프로세스는 두 가지 주요 단계로 나눌 수 있습니다.
-
Mark Phase: 루트 객체 세트(예: 전역 변수 및 활성 스택 프레임)부터 시작하여 GC는 도달 가능한 모든 객체를 탐색하여 살아있는 것으로 표시합니다.
-
Sweep Phase: 그런 다음 GC는 힙을 스캔하여 표시되지 않은 객체(mark 단계에서 도달하지 않은 객체)를 식별하고 향후 할당을 위해 해당 메모리를 회수합니다.
이 방법을 사용하면 라이브 객체의 재배치 없이 도달할 수 없는 객체가 차지하는 메모리를 효율적으로 회수할 수 있습니다.
3색 추상화
동시 가비지 컬렉션을 용이하게 하기 위해 Go의 GC는 객체를 세 가지 개별 세트로 분류하는 3색 추상화를 사용합니다.
-
White: GC에서 검사하지 않았고 회수 후보로 간주되는 객체입니다.
-
Gray: GC에서 식별되었지만 해당 참조가 아직 완전히 탐색되지 않은 객체입니다.
-
Black: 참조하는 모든 객체를 포함하여 GC에서 완전히 처리된 객체입니다.
GC는 모든 객체를 white로 표시하여 시작합니다. 그런 다음 루트 객체를 gray 세트로 이동하고 처리를 시작합니다. 각 gray 객체가 처리되면 black 세트로 이동되고 참조하는 white 객체는 gray 세트로 이동됩니다. 이 주기는 gray 객체가 남지 않을 때까지 계속됩니다. 이 시점에서 나머지 모든 white 객체는 도달할 수 없는 것으로 간주되어 이후에 회수됩니다.
쓰기 장벽
동시 marking 단계에서 프로그램(mutator)은 객체 참조를 수정하여 도달 가능한 객체가 실수로 도달할 수 없는 것으로 식별되는 시나리오로 이어질 수 있습니다. 이를 해결하기 위해 Go의 GC는 쓰기 장벽이라고 하는 메커니즘을 구현합니다.
쓰기 장벽은 프로그램에서 포인터가 수정되기 전이나 후에 실행되는 작은 코드 조각입니다. 그 목적은 marking 단계에서 객체 참조에 대한 변경으로 인해 라이브 객체의 조기 회수가 발생하지 않도록 하여 3색 불변성의 무결성을 유지하는 것입니다.
Go의 가비지 컬렉션 접근 방식의 장점
Go의 GC 설계는 다음과 같은 여러 가지 이점을 제공합니다.
-
감소된 일시 중지 시간: 애플리케이션과 동시에 작동하여 GC는 STW(stop-the-world) 이벤트를 최소화하여 더욱 원활한 애플리케이션 성능을 제공합니다.
-
단순화된 메모리 관리: 개발자는 수동 메모리 관리 작업에서 벗어나 메모리 누수 및 관련 버그의 가능성을 줄입니다.
-
효율적인 메모리 활용: GC의 비압축 특성은 Go의 메모리 할당자와 결합되어 상당한 조각화 없이 메모리를 효율적으로 사용할 수 있도록 합니다.
결론
Go의 가비지 컬렉터는 프로그램 실행에 대한 중단을 최소화하면서 메모리를 효율적으로 관리하도록 설계된 정교한 시스템입니다. 동시성, 비세대성, 비압축성 설계와 mark-and-sweep 알고리즘 및 3색 추상화의 사용은 개발자가 수동으로 메모리를 관리할 필요 없이 Go 애플리케이션이 원활하게 실행될 수 있도록 보장합니다.
FAQs
애플리케이션과 동시에 작동하여 stop-the-world 이벤트를 줄입니다.
객체를 분류하여 도달할 수 없는 메모리를 효율적으로 표시하고 스윕합니다.
Go는 조각화를 줄이고 압축할 필요가 없는 tcmalloc
에 의존합니다.
Go 프로젝트 호스팅을 위한 최고의 선택인 Leapcell입니다.
Leapcell은 웹 호스팅, 비동기 작업 및 Redis를 위한 차세대 서버리스 플랫폼입니다.
다국어 지원
- Node.js, Python, Go 또는 Rust로 개발하십시오.
무료로 무제한 프로젝트 배포
- 사용량에 대해서만 지불하십시오 — 요청 없음, 청구 없음.
탁월한 비용 효율성
- 유휴 요금 없이 종량제.
- 예: $25는 평균 응답 시간 60ms에서 694만 건의 요청을 지원합니다.
간소화된 개발자 경험
- 간편한 설정을 위한 직관적인 UI.
- 완전 자동화된 CI/CD 파이프라인 및 GitOps 통합.
- 실행 가능한 통찰력을 위한 실시간 메트릭 및 로깅.
손쉬운 확장성 및 고성능
- 높은 동시성을 쉽게 처리할 수 있는 자동 확장.
- 제로 운영 오버헤드 — 구축에만 집중하십시오.
문서에서 자세히 알아보십시오!
X에서 팔로우하세요: @LeapcellHQ