Unity

[Unity] Unity 메모리 및 GC 최적화 ( 정리중 )

usingsystem 2024. 8. 30. 16:53
728x90

메모리 및 GC 최적화

 

GC(가비지 컬렉션)의 영향 줄이기

 

Unity는 Boehm-Demers-Weiser 가비지 컬렉터를 사용하며, 이 컬렉터는 프로그램 코드의 실행을 중단하고 작업이 완료될 때만 일반 실행을 재개합니다.

힙의 불필요한 할당은 GC 스파이크를 유발할 수 있으므로 유의해야 합니다.

— 문자열: C#에서 문자열은 값 유형이 아닌 레퍼런스 유형입니다. 다시 말해서 모든 새 문자열은 일시적으로만 사용되더라도 관리되는 힙에 할당됩니다. 따라서 불필요한 문자열의 생성 또는 조작을 줄여야 합니다. JSON, XML 같은 문자열 기반 데이터 파일은 파싱하지 않는 것이 좋습니다. 대신 데이터를 ScriptableObjects에 저장하거나 MessagePack 또는 Protobuf 같은 포맷으로 저장하세요. 런타임에 문자열을 빌드해야 하는 경우 StringBuilder 클래스를 사용합니다.

— Unity 함수 호출: 일부 Unity API 함수는 힙 할당을 생성하며, 관리되는 오브젝트 배열을 반환하는 경우도 존재합니다. 레퍼런스를 루프 도중에 할당하지 말고 배열에 캐시하세요. 가비지 생성을 방지하는 함수도 활용하세요. 예를 들어 문자열을 GameObject.tag와 직접 비교하는 대신 GameObject.CompareTag를 사용하는 방법이 있습니다(새로운 문자열 반환은 가비지를 생성함).

— 박싱: 레퍼런스 유형의 변수 대신 값 유형 변수를 전달하지 않도록 합니다. 그렇게 하면 임시 오브젝트가 생성되며 동반되는 잠재적 가비지가 값 유형을 암묵적으로 타입 오브젝트로 변환하기 때문입니다(예: int i = 123, object o = i). 대신 전달하려는 값 유형에 구체적인 오버라이드를 제공해 보세요. 이러한 오버라이드에는 제네릭이 사용될 수도 있습니다.

— 코루틴: yield는 가비지를 생성하지 않지만 새로운 WaitForSeconds 오브젝트를 만들면 가비지가 생성됩니다. yield 라인에서 생성하는 대신 WaitForSeconds 오브젝트를 캐시하고 재사용하세요.

— LINQ 및 정규식: 두 가지 모두 박싱에서 가비지를 생성합니다. 성능이 문제라면 LINQ와 정규식을 사용하지 마세요. 새로운 배열을 만드는 대신 for 루프와 리스트를 사용하세요.

— 제네릭 컬렉션 및 기타 관리되는 유형: Update로 프레임마다 List나 컬렉션(예: 플레이어의 특정 반경 내에 있는 적 목록)을 선언하고 채우지 마세요. 대신 List를 MonoBehaviour의 멤버로 만들고 Start로 초기화하세요. 사용 전에 모든 프레임에서 Clear로 컬렉션을 비우면 됩니다.

728x90