오늘의 질문
Unity에서 가비지 컬렉션이 성능에 미치는 영향과 최적화 방법에 대해 설명하세요.
오늘의 대답
가비지 컬렉션은 사용하지 않는 메모리를 자동으로 해제하는 시스템입니다.
Unity에서 GC가 실행되면 게임이 일시적으로 멈추는 프레임 드롭 현상이 발생할 수 있습니다.
최적화 방법으로는 불필요한 객체 생성을 줄이고, 오브젝트 풀링을 활용하며, 값 타입 사용을 늘리는 것이 있습니다.
또한 Update문에서 임시 객체 생성을 피하고, StringBuilder나 캐싱을 활용하여 GC 발생 빈도를 줄이는 것이 중요합니다.
가비지 컬렉션 ?
사용하지 않는 메모리를 자동으로 정리하는 시스템
- C#의 자동 메모리 관리 기능
- C++과 달리 개발자가 직접 메모리를 해제할 필요 없음
- 참조되지 않는 객체를 찾아서 메모리에서 제거
- GC 실행 중에는 프레임 드랍 발생
발생 시점
- 힙 메모리가 부족할 때
- 많은 임시 객체가 생성되었을 때
- GC.Collect()
- 씬 전환이나 대용량 리소스 로드 시
원인과 회피 방법
- 반복된 new => 캐싱된 값 재사용
- 문자열 수정 => StringBuilder
- 박싱과 언박싱 => 제너릭
- LINQ => 반복문
- 오브젝트의 반복된 Instantiate와 Destroy => 오브젝트 풀링으로 재사용
- 리스트 크기가 자주 변할 때 => 초기 용량 설정
- 람다식 캡처 => 미리 선언된 메서드
- 람다식이 바깥에 있는 변수를 가져다 쓰면 캡처 발생! 임시 객체 생성으로 GC 발생
- 참조 타입 => 값 타입
잠깐 !
왜 참조타입 보다는 값 타입일까 ?
- 참조 타입인 class는 힙 메모리에 저장 -> GC가 관리
- 값 타입인 struct는 스택 메모리에 저장 -> 스코프 끝나면 자동 해제
내 생각... 값 타입은 복사되니까 더 많은 메모리를 차지하는데도 값 타입이 더 효율적인 게 맞나 ?
=> 값 타입은 복사 비용이 있지만 GC 비용에 비해 싸다. 작은 데이터에 한해서.
큰 데이터의 경우 메모리 측면에서 참조 타입이 더 나을 수 있다.
Unity에서 Vector3, Quaternion이 값 타입인 이유.
- 값 타입이 좋은 경우
- 작은 데이터
- 자주 생성 / 소멸되는 데이터
- 불변 데이터
- 참조 타입이 좋은 경우
- 큰 데이터
- 긴 생명주기를 가진 객체
- 상속이나 null 상태가 필요한 경우