한국어English日本語简体中文繁體中文DeutschไทยTiếng ViệtРусскийPortuguês (Brasil)EspañolBahasa Indonesia

게임 렉 백서 › L1 클라이언트 게임 프로세스

클라이언트 가비지 컬렉션 Client GC (Unity C#, Unreal, Lua)

원인 ID cg-gc · 주 담당 게임개발팀·클라이언트 개발

그림과 실험이 있는 원본 카드로 열기 →

쓰고 버린 메모리(가비지)를 회수하는 동안 게임 전체가 멈춥니다. 규칙적인 간격으로 뚝뚝 끊기는 것이 특징입니다.

왜 매 프레임 임시 문자열·배열·리스트를 만들고 버림 → 그러면 가비지가 쌓이면 GC가 메인 스레드를 멈추고 회수 → 화면에서는 몇 초~몇십 초마다 규칙적으로 뚝뚝 끊김

증상
뚝뚝 끊김, 멈춤
요인
정체
누가 겪나
나만
언제
일정한 주기로, 사람이 몰릴 때
담당
주 담당 게임개발팀·클라이언트 개발
게임개발팀 할 일
할당 줄이기(문자열 합치기·LINQ·람다 캡처 피하기), 오브젝트 풀, 점진적 GC 켜 두기(유니티 2020 이후 기본값), 로딩 화면처럼 멈춰도 괜찮은 때에 미리 GC 돌리기.
수치 감각
보통 한 번에 수 ms~100ms, 저사양 폰이나 메모리를 많이 쓰는 게임은 그 이상(실험은 약 150~170ms). 유니티의 GC는 돌 때마다 힙 전체를 검사해서 게임이 쓰고 있는 메모리가 많을수록 길어집니다.
그래프에서는
일정 주기로 튐 · 프레임 시간, GC 실행 시각
확인할 곳
개발 빌드에서 유니티 프로파일러의 GC.Collect·GC.Alloc 마커를 봄. 언리얼은 stat GC와 stat Hitches(t.HitchFrameTimeThreshold로 정한 시간을 넘는 프레임을 로그로 남김)
이러면 맞음
튄 프레임마다 GC.Collect 구간이 있고 그 길이가 튄 길이와 비슷하며, 간격이 몇 초~몇십 초로 규칙적임. 사람 많은 곳에서 프레임당 GC.Alloc이 늘어남
이러면 아님
튄 프레임에 GC 구간이 없으면 “메인 스레드 동기 로딩·셰이더 컴파일”이나 “대규모 인원 렌더링 부하”
확인 수단
게임 서버·클라이언트의 로그·지표가 필요
더 알아보기
유니티처럼 C#을 쓰는 클라이언트에서 흔합니다. 전투 로그 문자열, 데미지 숫자, UI 텍스트를 매 프레임 새로 만드는 코드가 가장 흔한 원인입니다. 사람 많은 곳에서만 끊긴다면 인원에 비례해 가비지가 늘어나는 코드가 원인입니다. 점진적 GC는 한 프레임에 조금씩(유니티 기본 3ms) 나눠 수집하지만 수집하는 속도보다 가비지를 빨리 만들면 결국 한 번에 멈춥니다. 언리얼 엔진에도 안 쓰는 게임 오브젝트를 정리하는 자체 GC가 있고 엔진 버전·설정에 따라 다르지만 기본 설정으로 약 1분마다 돌아 1분 간격의 멈칫을 만들기도 합니다. 게임 규칙을 Lua 같은 스크립트로 짠 클라이언트는 그 스크립트의 GC도 따로 돕니다.

출처

  1. Garbage collection modes Unity
    점진적 GC가 기본값이고 여러 프레임에 나눠 수집, 끄면 힙 전체를 검사하는 동안 메인 스레드가 멈추며 수백 ms까지 갈 수 있음
  2. Scripting.GarbageCollector.CollectIncremental Unity
    점진적 GC가 한 번에 쓰는 시간(타임 슬라이스)의 기본 목표는 3ms(incrementalTimeSliceNanoseconds)
  3. Garbage Collection Settings in the Unreal Engine Project Settings Epic Games
    언리얼 GC가 정해진 간격(Time Between Purging Pending Kill Objects, 초 단위)으로 돈다는 설정. 기본값 숫자는 이 문서에 없음
  4. Profiler markers reference Unity
    GC.Collect: 가비지 컬렉션 동안 프로그램 코드가 멈춘 구간(1ms 미만~수백 ms), GC.Alloc: 관리 힙 할당
  5. Stat Commands in Unreal Engine Epic Games
    stat GC(가비지 컬렉션 통계), stat Hitches(t.HitchFrameTimeThreshold를 넘는 프레임을 로그에 기록)

함께 보면 좋은 원인

같은 층: L1 클라이언트 게임 프로세스

같은 증상(뚝뚝 끊김)의 다른 층 원인

그림과 실험이 있는 원본 카드 보기