한국정보기술진흥원한국인공지능올림피아드 (KOAI) 2026 개최안내

유니티 게임 끊김의 주범은 '가비지 컬렉션'...힙 할당 줄여야 프레임 멈춤 막는다

자동 메모리 관리와 가비지 컬렉션 최적화 원리
[한국정보기술신문] 게임 엔진 유니티(Unity)의 게임 실행 도중 화면이 잠깐씩 멈추는 현상의 원인으로 꼽히는 '가비지 컬렉션'의 작동 원리와, 이를 줄이기 위한 메모리 관리 방법을 소개한다. 오브젝트나 문자열, 배열을 만들어 저장하려면 '힙(heap)'이라 부르는 중앙 메모리 공간에서 자리를 할당받아야 하며, 더 이상 쓰이지 않는 자리는 회수해 다른 데이터를 담는 데 다시 쓰게 된다. 힙은 프로그램이 실행 중에 데이터를 쌓아 두는 공용 저장 공간을 말한다.
과거에는 프로그래머가 직접 함수를 호출해 힙의 메모리 공간을 할당하고 회수해야 했다. 그러나 유니티가 사용하는 모노(Mono) 엔진과 같은 최신 실행 환경은 이 과정을 자동으로 처리한다. 자동 메모리 관리가 직접 할당하고 회수하는 방식보다 코딩 부담이 적고, '메모리 누수' 가능성도 낮춘다. 메모리 누수란 한번 할당된 메모리가 끝내 회수되지 않고 계속 쌓이는 현상을 말한다.
fotis-fotopoulos-6sAl6aQ4OWI-unsplash.jpg
Unsplash 제공

값 타입과 레퍼런스 타입의 차이

데이터를 다루는 방식은 크게 두 가지로 나뉜다. 함수가 호출되면 그 함수에 넘겨지는 값이 별도의 메모리 구역에 복사되는데, 정수나 소수처럼 크기가 몇 바이트에 불과한 데이터는 빠르게 복사할 수 있다. 이처럼 사본이 직접 저장되는 데이터를 '값 타입'이라 한다. 정수, 부동소수점, 참·거짓을 나타내는 부울, 그리고 색을 나타내는 컬러(Color)나 3차원 위치를 담는 벡터3(Vector3) 같은 유니티의 구조체가 여기에 속한다.
반면 오브젝트나 문자열, 배열은 크기가 큰 경우가 많아 매번 통째로 복사하면 대단히 비효율적이다. 유니티는 이런 큰 데이터의 실제 내용을 힙에 저장해 두고, 그 위치를 가리키는 작은 '포인터' 값만 주고받는 방식을 쓴다. 포인터는 데이터가 어디 있는지를 알려 주는 일종의 주소표다. 이렇게 힙에 저장한 뒤 포인터로 접근하는 데이터를 '레퍼런스(참조) 타입'이라 부르며, 변수에는 실제 값이 아니라 그 데이터를 '참조'하는 정보만 담긴다. 데이터를 한 번만 저장해 두고 여러 곳에서 함께 쓸 수 있다는 것이 장점이다.

쓰지 않는 메모리를 찾아 비우는 '가비지 컬렉션'

메모리 관리자는 힙에서 비어 있는 영역을 계속 추적한다. 유니티는 새 오브젝트가 만들어지는 등 메모리 블록이 요청되면 관리자는 비어 있는 자리를 골라 할당하는데, 이 과정이 반복되다 보면 더 이상 필요한 크기의 빈 공간을 찾기 어려운 시점에 이른다. 그러나 이때 힙에 할당된 메모리가 모두 실제로 쓰이고 있을 가능성은 낮다. 어떤 데이터를 가리키던 변수가 다른 값으로 바뀌거나 사라지면, 그 데이터가 차지하던 메모리는 다시 쓸 수 있는 상태가 되기 때문이다.
관리자는 어떤 메모리가 더 이상 쓰이지 않는지 가려내기 위해, 현재 살아 있는 모든 참조 변수를 훑어 이들이 가리키는 블록을 '살아 있음(live)'으로 표시한다. 검색이 끝나면 살아 있는 블록 사이의 나머지 공간은 비어 있는 것으로 간주해 다음 할당에 쓴다. 이렇게 쓰이지 않는 메모리를 찾아 해제하는 과정을 '가비지 컬렉션(garbage collection, GC)'이라 부른다.
가비지 컬렉션이 프로그래머 눈에 보이지 않게 자동으로 일어나지만, 실제로는 상당한 처리 시간을 잡아먹는다. 제대로 관리하면 자동 메모리 관리는 수동 방식과 비슷하거나 더 나은 성능을 내지만, 가비지 컬렉터가 필요 이상으로 자주 실행되면 게임 도중 화면이 멈추는 현상을 일으킬 수 있다는 것이다. 따라서 이런 실수를 막는 것이 중요하다.

무심코 쓴 코드가 'GC 악몽' 부른다

처음에는 문제없어 보여도 나중에 가비지 컬렉션을 폭증시키는 대표적 사례로 '문자열 연결의 반복'이 있다. 여러 조각의 문자를 더해 하나의 문자열을 만드는 코드를 반복 실행하면, 겉보기에는 기존 문자열에 새 조각이 덧붙는 것처럼 보인다. 그러나 실제로는 반복할 때마다 기존 내용을 지우고, 합쳐진 새 문자열을 통째로 새로 할당한다. 문자열이 길어질수록 쓰는 힙 공간도 커져, 함수를 호출할 때마다 순식간에 수백 바이트의 빈 공간을 소모한다. 여러 문자열을 한꺼번에 이어 붙여야 한다면 모노 라이브러리의 스트링빌더(StringBuilder) 클래스를 사용하는 것을 권장한다.
이런 문자열 연결도 너무 자주 실행되지만 않으면 큰 문제가 되지 않는다. 다만 화면을 새로 그리는 매 프레임마다 점수 표시 등을 위해 문자열을 새로 만드는 코드를 경계해야 한다. 점수가 바뀔 때만 문자열을 새로 만들도록 조건을 두면 불필요한 메모리 낭비를 크게 줄일 수 있다는 것이다.
함수가 배열을 결과로 돌려주는 경우도 비슷한 문제를 낳는다. 값으로 채운 새 배열을 만들어 반환하는 함수는 쓰기 편하지만, 자주 호출하면 매번 새 메모리를 할당한다. 배열은 대체로 크기가 커 빈 힙 공간이 빠르게 소모되고, 그만큼 가비지 컬렉션도 잦아진다. 배열이 레퍼런스 타입이라는 점을 활용해, 새 배열을 만들어 돌려주는 대신 미리 만들어 둔 배열을 함수에 넘겨 그 안의 값만 바꾸는 방식을 사용할 수 있다. 함수에 넘긴 배열의 수정 결과는 함수가 끝난 뒤에도 유지되므로, 호출할 때마다 새 가비지가 생기지 않는다.

힙 크기 조절로 끊김 최소화

할당을 최대한 피하는 것이 최선이지만 완전히 없앨 수는 없다. 가비지 컬렉션이 게임 진행에 주는 영향을 줄이는 두 가지 전략을 제시한다.
첫째는 '작은 힙과 빠르고 잦은 가비지 컬렉션'이다. 작은 메모리 블록을 자주, 그러나 짧게만 쓰는 게임에 적합한 방식이다. 유니티에 따르면 iOS에서 힙 크기가 200KB일 때 아이폰 3G에서 가비지 컬렉션에 약 5밀리초가 걸리고, 힙이 1MB로 커지면 7밀리초가량 걸린다. 일정한 프레임 간격마다 일부러 가비지 컬렉션을 요청하면, 컬렉션이 실제 필요한 것보다 자주 일어나는 대신 그때그때 빠르게 끝나 게임 진행에 주는 지장을 최소화할 수 있다. 다만 이 기법이 실제로 컬렉션 시간을 줄이는지 측정 도구(프로파일러)로 확인해야 한다.
둘째는 '큰 힙과 느리지만 드문 가비지 컬렉션'이다. 메모리 할당과 컬렉션이 비교적 드물어 게임 도중 처리할 여유가 있는 경우에 알맞다. 힙은 가능한 한 크게 잡되, 운영체제가 메모리 확보를 위해 앱을 강제 종료할 만큼 커서는 안 된다. 모노 실행 환경은 힙을 자동으로 늘리는 것을 되도록 피하므로, 시작 단계에서 의미 없는 임시 데이터를 미리 할당했다가 풀어 주는 방식으로 힙을 수동으로 키워 둘 수 있다. 충분히 큰 힙을 확보하면 게임 진행 중 힙이 가득 차 갑자기 컬렉션이 일어나는 일을 피할 수 있고, 게임이 잠시 멈추는 시점에 맞춰 직접 컬렉션을 요청할 수 있다. 이 전략 역시 원하는 효과가 나는지 프로파일러 통계로 거듭 확인해야 한다.

오브젝트 재사용으로 가비지 줄이기

가장 단순한 해법으로 '오브젝트 재사용'도 제시한다. 새로 만들고 없애는 오브젝트의 수 자체를 줄이면 가비지 생성도 줄어든다는 것이다. 게임에는 총알이나 발사체처럼 여러 번 반복해 등장하지만 한 번에 몇 개만 화면에 쓰이는 오브젝트가 많다. 이런 경우 매번 새 오브젝트를 만들어 기존 것을 버리기보다, 만들어 둔 오브젝트를 돌려쓰는 편이 낫다. 미리 일정 수의 오브젝트를 만들어 두고 꺼내 쓰다가 다시 반납하는 이 방식을 '오브젝트 풀(object pool)'이라 한다.
엔진 버전에 따라 가비지 컬렉터의 구체적 동작과 권장 방식은 달라질 수 있으므로, 실제 적용 시에는 사용하는 버전의 최신 설명을 함께 확인할 필요가 있다.
한국정보기술신문 실감형콘텐츠분과 강문영 기자 news@kitpa.org

함께 읽으면 좋은 기사

[백준 서비스 종료 ⑫] 데이원컴퍼니, 같은 날 'BOJ 부활'과 '개인정보 유출' 동시에...코딩 테스트 명소 백준 온라인 저지 되살리며 보안 사고로 신뢰 시험대

[백준 서비스 종료 ⑫] 데이원컴퍼니, 같은 날 'BOJ 부활'과 '개인정보 유출' 동시에...코딩 테스트 명소 백준 온라인 저지 되살리며 보안 사고로 신뢰 시험대

정보기술 5
유니티 게임 끊김의 주범은 '가비지 컬렉션'...힙 할당 줄여야 프레임 멈춤 막는다

유니티 게임 끊김의 주범은 '가비지 컬렉션'...힙 할당 줄여야 프레임 멈춤 막는다

실감형콘텐츠 5
넥슨, '크레이지 아케이드' 8월 13일 서비스 종료...25년 만에 막 내려, 환불 신청은 9월 16일까지

넥슨, '크레이지 아케이드' 8월 13일 서비스 종료...25년 만에 막 내려, 환불 신청은 9월 16일까지

정보기술 · 실감형콘텐츠 2
구글, 텍스트 4배 빠르게 짓는 실험 모델 '디퓨전젬마' 공개...토큰 하나씩 잇는 대신 256개 한꺼번에 생성, 26B MoE 구조로 소비자용 GPU서 구동

구글, 텍스트 4배 빠르게 짓는 실험 모델 '디퓨전젬마' 공개...토큰 하나씩 잇는 대신 256개 한꺼번에 생성, 26B MoE 구조로 소비자용 GPU서 구동

인공지능 4
앤트로픽, 미토스급 모델에 30일 데이터 보관·검토 도입...6월 9일 시행, 오용 패턴 탐지 위한 안전 조치

앤트로픽, 미토스급 모델에 30일 데이터 보관·검토 도입...6월 9일 시행, 오용 패턴 탐지 위한 안전 조치

인공지능 3
구글, 학생·학부모 기말시험 대비 위한 'AI 학습 도구 5가지' 소개...자료 한데 모아 학습 가이드·맞춤 퀴즈 만들고 유튜브엔 사용시간 제한·자녀 보호 기능까지

구글, 학생·학부모 기말시험 대비 위한 'AI 학습 도구 5가지' 소개...자료 한데 모아 학습 가이드·맞춤 퀴즈 만들고 유튜브엔 사용시간 제한·자녀 보호 기능까지

교육 · 정보기술 · 인공지능 3
기후에너지환경부, 전기차 공공충전 봄철 주말 할인 실적 공개...17일간 7만9천여 건 충전·7천5백만 원 환원, 낮 시간대 이용 9.2% 늘어

기후에너지환경부, 전기차 공공충전 봄철 주말 할인 실적 공개...17일간 7만9천여 건 충전·7천5백만 원 환원, 낮 시간대 이용 9.2% 늘어

유관기관 2
설치 없이 브라우저로 돌리는 오픈소스 지리정보시스템 'GeoLibre' 공개...PC·웹·모바일서 같은 화면으로 위성·드론 지도 다루고 공간 SQL·파이썬 연동까지

설치 없이 브라우저로 돌리는 오픈소스 지리정보시스템 'GeoLibre' 공개...PC·웹·모바일서 같은 화면으로 위성·드론 지도 다루고 공간 SQL·파이썬 연동까지

정보기술 4
구글, 크롬 AI 비서 '제미나이' 신흥 시장으로 확대...중남미·아프리카·중동 등 데스크톱·iOS 이용자에 적용, 이미지 변환·맞춤형 답변 기능도 추가

구글, 크롬 AI 비서 '제미나이' 신흥 시장으로 확대...중남미·아프리카·중동 등 데스크톱·iOS 이용자에 적용, 이미지 변환·맞춤형 답변 기능도 추가

인공지능 · 정보기술 2
일부 참여자만 '적대적 훈련'해도 AI 방어력 오른다...공주대·조선대 연구팀, 연합학습 강건성 실험 결과 공개

일부 참여자만 '적대적 훈련'해도 AI 방어력 오른다...공주대·조선대 연구팀, 연합학습 강건성 실험 결과 공개

인공지능 · 정보보안 4
컴퓨터 비전 라이브러리 'OpenCV 5' 정식 출시...DNN 엔진 새로 짜 ONNX 80% 넘기고 LLM·VLM까지 직접 구동

컴퓨터 비전 라이브러리 'OpenCV 5' 정식 출시...DNN 엔진 새로 짜 ONNX 80% 넘기고 LLM·VLM까지 직접 구동

인공지능 · 정보기술 4
신경망을 반도체 회로로 직접 새긴다...FPGA에 'KAN' 올려 나노초급 추론·실시간 학습 구현...연구진 "기존 KAN-FPGA보다 2700배 빨라"

신경망을 반도체 회로로 직접 새긴다...FPGA에 'KAN' 올려 나노초급 추론·실시간 학습 구현...연구진 "기존 KAN-FPGA보다 2700배 빨라"

인공지능 · 정보통신 4