[Unity] 가비지 컬렉션(Garbage Collection)

WestCoast·2022년 5월 28일
0

Unity

목록 보기
1/5

메모리 할당


  • 메모리 관리자가 힙에서 사용되지 않는 영역을 조사.
    오브젝트 생성 등의 메모리 할당 요청이 일어나면, 관리자가 할당되어 있지만 사용하지 않는 메모리 제거. 이 과정은 메모리 할당을 할 수 있을만한 크기의 메모리가 확보될 때까지 반복된다.

Unity의 가비지 컬렉션


  • 힙 블록이 사용되고 있는지 확인하기 위해서 메모리 관리자는 모든 참조 변수를 검색하고 이 참조 변수가 가리키고 있는 힙 영역의 블록에 “live”라고 표시한다.(mark-and-sweep과 비슷한 얘기)
    검색이 끝나면 메모리 관리자는 살아있는 블록 사이의 모든 공간을 비어있다고 판단하고 다음 할당 요청이 일어날 때 사용할 수 있다고 판단한다.

  • Unity는 Boehm 가비지 컬렉터를 사용한다. 기본적으로는 점진적(Incremental) 가비지 컬렉션 방식을 사용한다.
    점진적 가비지 컬렉션을 비활성화하고 “stop-the-world” 가비지 컬렉션을 사용할 수도 있지만, 점진적 가비지 컬렉션 방식을 권장한다.

Incremental 모드와 stop-the-world 모드를 전환하려면 Edit > Project Settings > Player 메뉴의 Other Settings 패널에서 설정할 수 있다.

  • Stop-the-world 가비지 컬렉션
    GC가 일어나는 중에는 다른 작업(다른 스레드 등)을 모두 중지한다.
    Unity는 가비지 컬렉션을 수행할 때마다 프로그램 코드들의 실행을 중지하고, 가비지 컬렉터가 모든 작업을 마친 후에야 다시 일반적인 실행을 재개한다. 이 때 GC가 처리할 것이 많을수록 GC가 일어나는 시점에 게임이 멈춘 것처럼(렉, 프레임 드랍) 보일 수 있다.
    이렇게 프레임 드랍이 일어날 때 프로파일러 프레임 시간 그래프에서 높게 치솟은 모양을 보고 ‘GC 스파이크’라고 부른다.
  • 점진적 가비지 컬렉션(Incremental GC)
    GC를 한 프레임에 모두 처리하지 않고 여러 프레임에 나누어서 처리한다. 갑작스러운 프레임 드랍을 방지할 수 있다.

최적화


“처음에는 아무 문제 없어 보일지라도 이후 GC의 악몽을 불러올 수 있는 악명 높은 알고리즘이 일부 존재합니다. 가장 잘 알려진 사례로 문자열 접합 반복이 있습니다.”

  1. 문자열 함부로 계속 이어붙이고 수정하지 마라. 심지어 Update 문에서 for문으로 string 접합하는 알고리즘은 제발 하지 마라. 계속해서 string 객체가 재할당되고 쓸모없어진 이전 string 객체는 가비지 컬렉팅의 대상이 된다.
    대신 System.Text.StringBuilder를 사용해라.

  2. 함수에서 새로운 배열을 생성해서 반환하지 마라. 함수 매개변수로 배열을 넘겨서 원본 배열의 원소들을 함수에서 수정해라. 배열은 일반적으로 크기가 크다.
    배열 생성을 자주하면 힙 공간이 빠르게 줄어들고 자주 가비지 컬렉션을 해야한다.
    오브젝트 풀을 사용하는 이유도 위와 비슷한 이유다.


연관 포스팅


참고

profile
게임... 만들지 않겠는가..

0개의 댓글