내가 이해한 오브젝트 풀링 개념

2025. 11. 12. 16:24·📖TIL

Question : 오브젝트 풀링이란 무엇인가요?

 

Answer : 오브젝트 풀링은 게임 개발에서 성능을 높이기 위해 사용하는 기법입니다.

 

게임에서 필히 오브젝트를 생성과 파괴를 하게 되는데요.
생성시 메모리를 할당하는 과정이 있고 파괴시 GC ( 가비지 콜렉터 )가 수거하는 과정에서 프레임 드랍이 생기게 됩니다.

GC 사용은 무겁기 때문에 GC 가 자주 수거해야 하는 상황이 오면 그만큼 프레임 드랍이 자주 발생합니다.

이러한 문제점을 해결하기 위해 오브젝트 풀링 기법을 사용합니다.

 

오브젝트 풀링은 자주 사용하게 될 오브젝트를 생성할 메모리를 미리 배열이나 리스트 등에 할당해놓고

필요할 때마다 꺼내서 쓰고 필요 없어지면 파괴가 아니라 비활성화해서 배열이나 리스트 등에 다시 넣는 기법입니다.

 

 

Question : 그럼 오브젝트 풀링을 사용할 때의 단점이나 주의할 점은 무엇인가요?

 

Answer : 

오브젝트 풀링의 단점으로는 미리 메모리 공간을 할당하기 때문에 풀링 기법으로 할당해놓고 자주 사용하지 않는다면 메모리 공간을 낭비하게 됩니다. 자주 사용할 오브젝트가 아닌데도 풀링 기법으로 할당 해놓으면 역시 메모리를 낭비하게 됩니다.

<보충 설명>
오브젝트 풀링은 미리 객체를 생성해두기 때문에 메모리 사용량이 증가할수 있다.
또한 , 풀의 크기를 잘못 설정하면 메모리 낭비나 부족 현상이 발생할수 있다.
그리고 풀링된 오브젝트를 재사용할 때 초기화가 제대로 되지 않으면 예기치 않은 동작
( 이전 상태가 남는 버그 )이 생길 수 있다.
마지막으로 풀을 관리하는 코드 복잡도가 올라가는 것도 단점이다.

 

Question : 그렇다면 풀링된 오브젝트를 재사용할 때 상태가 초기화되지 않아 문제가 생긴다고 했는데요.

이런 문제를 방지하기 위해 개발자가 취할 수 있는 방법에는 어떤 게 있을까요?

 

Answer : 

오브젝트 풀에서 객체를 가져올 때 항상 초기화하도록 명시적으로 코드를 작성해야 합니다.

<보충 설명>
풀에서 오브젝트를 꺼낼 때 항상 초기화 메서드를 호출하도록 명시적으로 관리한다.
OnSpawn() 이나 ResetState() 같은 메서드를 정의해
위치, 속도, 체력 등 이전 프레임의 데이터가 남지 않게 초기화한다.
풀에 반환할 때 ( OnDespawn )도 정리 작업을 해두면 다음 사용 시 안전하다.

 

Question : 좋습니다. 그럼 오브젝트 풀링을 Unity 에서 직접 구현한다면,

어떤 자료구조를 사용하는 것이 일반적이며 , 그 이유는 무엇인가요?

 

Answer : 

일반적으로는 List 제네릭을 사용합니다.

물론 상황에 따라 Queue 나 Array 등도 사용할 수 있습니다.

Array 사용시 풀에서 꺼내는 객체의 수가 Array 크기보다 클 때에는 문제가 발생하므로

일반적으로는 사용이 유연하게 크기를 조절할 수 있는 List 가 좋습니다.

<보충 설명>
보통 List<GameObject> 나 Queue<GameObject>를 많이 쓴다.
List 는 유연하게 크기를 조절할 수 있고 , 인덱스로 접근이 빠르다.
Queue 는 사용 / 반환 순서가 명확할 때 ( 총알처럼 FIFO 구조 )에 적합하다.

 

Question : 좋아요. 그럼 Unity 의 Instantiate() 와 SetActive(true)의 차이 관점에서,

오브젝트 풀링이 성능상 이점을 갖는 이유를 엔진 내부 동작 측면에서 설명해주실 수 있을까요?

 

Answer : 

Instantiate 할때 메모리를 할당해야 해서 성능 문제가 있고

SetActive(true) 는 이미 메모리에 할당된 객체를 활성화 하는 방법이라 프레임 드랍이 생기지 않습니다.

<보충 설명>
Instantiate 는 C# 과 Unity엔진 (C++) 영역 모두에서 새로운 GameObject 를 생성하고,
컴포넌트 초기화 Awake / Start 호출, 메모리 할당 등이 일어나기 때문에 매우 비싸다.
반면 SetActive(true)는 이미 존재하는 객체의 활성화 플래그만 변경하기 때문에
메모리 재할당이나 컴포넌트 재생성 없이 빠르게 처리된다.
그래서 오브젝트 풀링은 Instantiate() 호출 빈도를 줄여 GC와 프레임 드랍을 방지한다.

 

Question : 그렇다면 SetActive(true) 로 활성화할 때,

Unity의 생명주기 (Life Cycle) 중 어떤 콜백들이 다시 호출되나요?

 

Answer : 음.. 그 부분은 잘 모르겠습니다.

<보충 설명>
풀링된 객체가 다시 SetActive(true) 될 때는 Awake나 Start는 다시 호출되지 않고,
OnEnable() 이 다시 호출된다.
그래서 풀링된 오브젝트를 재사용할 때는 초기화 코드를 보통 OnEnable() 에 두는 편이다.

 

 

Question :

좋습니다. 그렇다면 OnEnable() 대신 초기화 메서드를 직접 호출하는 구조를 선호하는 개발자들도 있습니다.

이렇게 직접 초기화 메서드를 만드는 이유는 무엇일까요?

 

Answer : 코드 간결화를 위해서 그런 것 같습니다.

<보충 설명>
코드 간결화는 방향성이 완전히 틀린 것은 아니지만, 실제 이유는 조금 다르다.
코드 간결화 보다는 초기화 시점의 제어권을 개발자가 가지기 위해서가 더 정확한 이유이다.

OnEnable() 은 Unity 엔진이 오브젝트 활성화 시점을 감지해서 자동으로 호출하는 콜백이다.
"언제 실행될지 완전히 예측하기 어렵고 의도하지 않은 순서로 실행될 수 있다"
는 뜻이다.

그래서 실무에서는 직접 초기화 메서드 (Initialize() 나 ResetState() 등)를 만들어
풀에서 오브젝트를 꺼낼 때 명시적으로 호출한다.

 

 

Question : 좋습니다.

그러면 오브젝트 풀링을 너무 많이 사용했을 때 발생할 수 있는 엔진 레벨 부하나 병목 현상에는 어떤 것이 있을까요?

 

Answer : 오브젝트를 자주 사용해야 하는데 풀의 크기를 너무 낮게 잡으면 공간을 늘리는데 많은 연산량을 요구하므로 프레임 드랍이나 병목 현상이 발생할 수 있습니다.

<보충 설명>
유사 정답이다.
질문의 초점은 풀링 시스템이 너무 많을 때 발생하는 엔진 부하였다.
풀의 크기 조절보다는 풀 자체가 너무 많은 때 Unity 엔진 내부적으로 생길 수 있는 성능 병목을 묻는 질문이다.

오브젝트 풀리을 지나치게 남용하면 다음과 같은 문제가 발생한다.
1. 활성 / 비활성 오브젝트 수가 너무 많은 때 Scene 관리 부하
2. Update , Collider , Renderer 등 컴포넌트 관리 오버헤드
3. GC 관리 비용 증가
4. 풀 관리 스크립트의 연산 오버헤드

 

'📖TIL' 카테고리의 다른 글

251113 CSV & JSON  (0) 2025.11.13
251113  (0) 2025.11.13
251112 Particle  (0) 2025.11.12
251112 AudioSource  (0) 2025.11.12
251112 Object Pool  (0) 2025.11.12
'📖TIL' 카테고리의 다른 글
  • 251113 CSV & JSON
  • 251113
  • 251112 Particle
  • 251112 AudioSource
DevHoChan
DevHoChan
맨땅에서 시작하는 코딩 도전
  • DevHoChan
    Debugging Life
    DevHoChan
  • 전체
    오늘
    어제
    • 분류 전체보기 (374)
      • 🕹️Game Life (1)
      • 🖥️Computer Science (5)
      • 📖TIL (141)
        • 🔥Projects (16)
        • 💡DevTips (5)
        • 🤔발생한 문제와 해결 (5)
        • 🔮Unity Graphics (5)
        • 🎤Interview (3)
        • ✅CodingTest (9)
      • 🚀Game Release (4)
      • 🧊Unity Basic (58)
        • 📌용어 사전 (1)
        • 에디터&인터페이스 (3)
        • 디버그 (1)
        • 라이프사이클 (4)
        • 게임오브젝트 (4)
        • 프리팹 (1)
        • 오브젝트풀링 (4)
        • 애트리뷰트 (2)
        • 트랜스폼 (4)
        • 물리&충돌 (1)
        • 프레임&델타타임 (4)
        • 코루틴&이벤트 (7)
        • 수학&보정함수 (3)
        • 디자인패턴 (9)
        • UGUI (3)
        • 벡터 ( Vector ) (3)
        • 씬 ( Scene ) (2)
        • 데이터 관리 (2)
      • ⭐C Sharp (99)
        • 📌용어 사전 (1)
        • 📌문법 사전 (6)
        • 메모리 관리 (3)
        • 00. 문법 (17)
        • 01. 변수 (3)
        • 02. 자료형 (2)
        • 03. 연산자 (6)
        • 04. 조건문 (2)
        • 05. 반복문 (2)
        • 06. 배열 (3)
        • 07. 메서드(함수) (7)
        • 08. 열거형 (3)
        • 09. 구조체 (2)
        • 10. 참조 (2)
        • 11. 객체 지향 (11)
        • 12. 델리게이트 (3)
        • 13. 디자인 패턴 (7)
        • 14. LINQ (1)
        • 📂▼자료구조 (2)
        • 15-1. 제네릭 (3)
        • 15-2. 배열 (4)
        • 15-3. 리스트 (2)
        • 15-4. 스택과 큐 (2)
        • 15-5. 딕셔너리 해시테이블 (2)
        • 15-6. 트리와 그래프 (3)
      • 📊Algorithm (16)
        • BigO (2)
        • 정렬 (4)
        • 셔플 (2)
        • 탐색 (6)
        • 최적화 (1)
      • 📝Game Design (16)
      • 🤖​AI Tools (12)
        • AI 리뷰 분석 (6)
        • Player2 (0)
        • 3D 모델링 (1)
        • 2D 스프라이트 (0)
        • 이미지 (2)
        • 사운드 (1)
        • 동영상 (1)
        • 문서 (1)
      • 🌍Network (6)
      • 🌱Github (11)
        • 기본 개념 (7)
        • 명령어 (1)
        • 도구 활용 (1)
      • ⚙️Visual Studio (5)
        • 🔧설치 및 환경설정 (2)
        • ⌨️HotKey (1)
        • 🚨디버깅 (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    디자인패턴
    게임디자인
    csharp
    CodingTest
    OOP
    부트캠프
    til
    자료구조
    GitHub
    객체지향
    메모리관리
    gamedesign
    자료형
    문법
    algorithm
    유니티
    기획
    unity
    c#
    게임기획
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.4
DevHoChan
내가 이해한 오브젝트 풀링 개념
상단으로

티스토리툴바