[Unity] 관리되는 힙(Managed Heap)

WestCoast·2022년 5월 28일
0

Unity

목록 보기
2/5

관리되는 힙에 대한 이해


관리되는 힙(Managed Heap)

메모리 관리자가 자동으로 관리하는 메모리
간단하게 말하면 Unity에서 동적할당해서 생성된 오브젝트들은 관리되는 힙에 할당된다.

  • 유니티의 관리되는 힙(managed heap)은 축소보다 더 쉽게 확장될 수 있다. 그러니까 메모리를 먹는 괴물이 되기 쉽다는 뜻이다.

  • 유니티의 가비지 컬렉션 전략은 메모리 단편화가 일어나는데 이로 인해 크기가 커진 힙이 줄어드는 것을 방해할 수 있다.


관리되는 힙의 작업 방식 및 확장 이유


흰 박스 : 관리되는 힙에 할당된 메모리 용량
주황, 분홍, 파랑 등의 박스 : 힙에 할당되어있는 데이터 값들

  • 위 그림에서 비어있는 흰색 영역이 할당 가능한(사용 가능한) 힙 영역이다.
    만약 할당하고자 하는 데이터가 들어갈 공간이 없다면 관리되는 힙의 전체 크기를 늘린다.

  • Unity의 가비지 컬렉션은 Boehm GC 알고리즘을 사용한다.
    이 알고리즘은 세대 기반 가비지 컬렉션 방식이 아니고, 압축도 하지 않는다.
    비세대 기반이기 때문에 가비지 컬렉팅이 일어나면 모든 힙 영역을 정리해야만 한다.
    그렇기 때문에 힙이 클수록 GC의 성능이 떨어지는 것이다.


힙 영역의 오브젝트가 해제되면 그림의 빨간 원처럼 여유 공간이 생긴다.

  • 이 공간에는 크기가 같거나 작은 데이터만 들어올 수 있다.
    오브젝트를 할당할 때, 오브젝트는 항상 연속된 메모리 공간을 차지해야 한다.
    이로 인해 메모리 단편화(특히 외부 단편화와 비슷한 개념)가 일어난다.
    위 그림처럼 메모리가 비연속적으로 해제되다 보면 전체 사용 가능한 메모리 영역은 여유가 있더라도 크기가 큰 오브젝트는 할당할 수 없는 문제가 발생할 수 있다.


힙의 여유 공간보다 큰 오브젝트가 할당되어야 할 때

  • 이런 문제가 발생했을 때 Unity의 메모리 관리자는 두 개의 작업을 실행한다.
    1. 가비지 컬렉터가 실행되지 않았을 경우 한 번 가비지 컬렉팅을 해본다. 공간이 더 생길 수도 있으니까.
    2. 1의 과정을 거치고도 요청된 메모리 공간을 수용할만한 연속된 공간이 없다면 힙을 확장한다. 플랫폼에 따라 다르지만, 대부분 힙의 크기를 2배로 늘린다.

힙의 주요 문제점


  1. 일단 한 번 힙이 확장되면 힙의 여유 공간이 많이 있다고 하더라도 잘 축소하지는 않는다. 왜냐하면 후에 좀 더 큰 메모리 할당이 필요하게 되었을 때 축소했던 힙을 다시 확장하지 않기 위해서다.

  2. 힙이 축소될 경우에 줄어든 만큼의 힙을 다시 OS에게 돌려주긴 하는데 언제 해제가 될진 잘 모르니까 너무 믿지는 마라.

  3. 관리되는 힙이 사용하는 주소 공간은 ‘절대’ 운영체제에 반환되지 않는다.

  4. 32 비트 프로그램에서 힙의 확장과 수축이 반복해서 일어나면 주소 공간이 부족해질 수 있다. 이럴 경우 OS는 프로그램을 종료시킨다.
    하지만 64비트는 주소 공간이 충분하기 때문에 프로그램을 평생 실행시켜도 문제없다.


정리 및 여담


유니티의 가비지 컬렉팅 방식은 구리다.
그리고 아주 구시대적인 방법이다. 이미 마이크로소프트 .Net의 CLR은 가비지 컬렉션 방식을 점차 발전시키며 세대별 가비지 컬렉션, SOH, LOH 의 구분 등을 적용시켰다.

하지만 유니티는 MONO가 만들어진 시절의 가비지 컬렉팅 방식에서 조금 진화해서 가비지 컬렉팅을 한 프레임에 모두 처리하는 게 아닌 점진적 방식 즉, 여러 프레임에 나누어 가비지 컬렉팅을 조금씩 하도록 바꾸었지만 근본적인 해결은 하지 못했다.

메모리 할당도 간단히 말하면 크기가 크던 작던 모든 오브젝트를 같은 힙에 때려박고 공간이 부족하면 모든 힙 영역에 대해 가비지 컬렉팅을 해보고 그래도 안되면 힙을 두 배 늘려서 때려박는 식이다.

그리고 어느 시점에 가비지 컬렉팅이 되는가 역시 확실하게 장담할 수는 없다.
기본적으로는 힙 메모리가 한계에 도달하거나 새로운 오브젝트를 할당해야 하는데 공간이 부족할 때 일어난다고 예측은 할 수 있지만 이 외에도 플랫폼, 구동 환경, 여러 어플 사용 등으로 인해서 GC가 일어날 수 있다. 그리고 이 때마다 프레임 드랍이 일어날 수 있다.
GC로 인한 부하가 걸리면 프로파일링을 통해 GC를 손수 최적화 시켜줘야 한다.


참고

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

0개의 댓글