Go 서버의 지연이 튀는 시점에 GC도 자주 실행됩니다. GC가 원인인지 확인하고 메모리와 지연을 어떻게 조정하나요?
잠깐, 답변을 보기 전에
먼저 내 말로 설명해 볼까요?
답변과 점검 포인트 펼치기답변 접기
구두 답변
정의를 외우기보다, 원리와 조건을 연결해 설명해 보세요.
먼저 지연이 큰 시점과 GC 활동이 실제로 겹치는지 확인하겠습니다. Go GC는 대부분 동시 실행되지만, 짧은 정지뿐 아니라 GC가 쓰는 CPU나 애플리케이션의 할당 보조 작업도 처리 지연에 영향을 줄 수 있습니다. GC 횟수만 보고 원인이라고 단정하지는 않겠습니다.
GC를 원인으로 확정하기 전
GC는 더 이상 필요하지 않은 객체의 메모리를 회수하는 런타임 기능입니다. 살아 있는 객체의 양이 작아도 요청마다 임시 객체를 많이 만들고 버리면 회수 작업이 자주 필요할 수 있습니다. 반면 오래 살아 있는 캐시가 커지는 문제는 할당률과는 다른 축이므로 두 지표를 구분해야 합니다.
요청마다 작은 임시 객체를 많이 만드는 경로가 있다고 하겠습니다. 살아 있는 힙은 크지 않아도 할당 속도가 높으면 GC가 자주 일할 수 있습니다. 저는 할당 프로파일에서 어떤 호출이 객체를 만드는지 보고, 버퍼의 불필요한 복사나 포맷팅부터 줄이겠습니다. 풀을 쓰면 할당을 줄일 수 있지만 객체를 오래 붙잡아 살아 있는 힙과 구현 복잡성이 늘 수 있어 실제 재사용 이득을 확인해야 합니다.
할당률과 메모리 예산
GOGC를 높이면 일반적으로 더 큰 힙을 허용해 수집 빈도를 줄일 수 있지만 메모리 예산을 더 씁니다. GOMEMLIMIT도 전체 프로세스 메모리의 엄격한 상한으로 보지는 않겠습니다. 관리 밖의 메모리와 필요한 살아 있는 데이터가 있기 때문입니다. 먼저 할당 원인을 줄이고, 이후 실제 메모리 한도와 부하에서 설정을 비교하겠습니다. 성공 기준은 GC 횟수 감소가 아니라 오류 없이 처리하는 양과 p99, 메모리 여유가 함께 나아지는지입니다.
선택 기준과 검증
GC와 지연이 같은 시각에 보여도 큰 JSON 변환, 락 대기, 스케줄러 지연이 함께 원인일 수 있습니다. 실험군과 대조군의 입력·동시성·메모리 한도를 고정하고, 수집 횟수보다 p99·GC CPU·heap live·오류율을 비교하겠습니다. 버퍼 풀은 재사용률이 낮거나 트래픽 하강 뒤 객체를 오래 보유하면 오히려 생존 힙을 키우므로, 풀 보유량과 회수 후 RSS도 같이 확인하겠습니다.
Go의 추적 GC는 살아 있는 객체를 찾아 표시해야 하므로 단순한 힙 바이트뿐 아니라 포인터가 많은 그래프의 스캔 비용도 중요합니다. 같은 100MB라도 바이트 배열과 작은 포인터 객체가 얽힌 그래프는 스캔 특성이 다릅니다. 할당이 수집 진도보다 빨라지면 할당하는 고루틴이 표시 작업을 돕는 mark assist 때문에 요청 지연이 늘 수 있어, stop-the-world 시간만 짧다고 GC 영향을 배제하지 않겠습니다.
GOGC는 생존 힙을 기준으로 다음 수집 목표를 조절하고, GOMEMLIMIT는 런타임이 관리하는 메모리의 소프트 한도로 작동합니다. 살아 있어야 하는 데이터가 한도에 가까우면 GC를 반복해도 줄일 수 없어 CPU를 소모할 수 있습니다. 이 경우 설정을 더 낮추기보다 캐시·동시성·버퍼 상한을 줄여야 합니다. sync.Pool은 항목이 언제든 제거될 수 있는 임시 재사용 장치이므로 필수 저장소나 고정 용량 풀처럼 의존하지 않겠습니다.
득점 포인트
이해가 드러나는 지점을 확인해 보세요.
- GC 정지·CPU·할당 보조 비용을 요청 지연과 같은 축에서 본다.
- alloc과 in-use 메모리를 분리해 원인을 찾는다.
- GOGC·메모리 한도·풀 재사용의 비용을 실제 부하로 비교한다.
감점 포인트
놓치기 쉬운 조건과 오해를 짚어 보세요.
- GC 횟수와 요청 지연의 상관만으로 원인을 확정한다.
- GOGC를 높이면 메모리·지연이 모두 좋아진다고 말한다.
- GOMEMLIMIT를 프로세스 모든 메모리의 절대 상한으로 설명한다.
더 파고들 거리
하나 더 질문하며 이해의 범위를 넓혀 보세요.
- Go heap profile의 alloc_space는 큰데 inuse_space는 작습니다. 임시 할당 비용과 생존 객체 보유를 어떻게 구분하나요?
- 같은 바이트 크기라도 포인터가 많은 객체와 바이트 배열의 GC 스캔 비용은 왜 다른가요?
- 메모리 한도에 가까울 때 GOGC 조정과 캐시 축소 중 무엇을 먼저 할까요?
득점·감점 포인트는 학습용 자기 점검 기준이며, 특정 회사의 실제 채점표가 아닙니다.
원리부터 공부하고 싶다면
답변을 보충하는 개념·예제·슈도코드를 읽어 보세요.