DevRookie
Object
Pooling
2020.06.20
By TonyChoiMS
서론
오브젝트 풀링
실습
마무리
Index
01
02
03
04
서론
오브젝트의 생성과 삭제
게임을 개발함에 있어서 인스턴스의 생성과 삭제는 굉장히 빈번하게 일
어나게 됩니다.
오브젝트 생성과 삭제01
4
인스턴스의 생성과 삭제는 매우 무거운 작업입니다.
동적으로 생성된 인스턴스는 힙 메모리에 할당되고, 해당 메모리를 다시
해제해줘야하는 작업을 해야하기 때문이죠.
오브젝트 생성과 삭제01
5
- 오브젝트의 잦은 생성과 삭제는 메모리 단편화 문제가 생기게 됩니다.
* 외부 메모리 단편화
오브젝트 생성과 삭제01
6
- 오브젝트 풀링은 이러한 문제들을 해결하기 위해 사용되고 있습니다.
오브젝트 생성과 삭제01
7
Object Pooling이란?
이론
- 디자인 패턴의 일종(객체 풀[Object Pool])
- 짧게 사용하고 사라진 뒤에 다시 사용하는 오브젝트의 경우 매번 다시
생성/해제를 반복하게 되면 메모리 부하가 심해집니다.
- 객체를 매번 할당, 해제하지 않고 고정 크기 풀에 들어 있는 객체를 재
사용함으로써 메모리 사용 성능을 개선합니다.
- 메모리 단편화를 방지합니다.
Object Pooling02
9
- 화면에 보이지 않게만 하고(Deactive) 메모리를 해제하지 않은 채로 필
요할 때마다 다시 사용하는 기법
- 메모리 할당을 더 간단하게 할 수 있고, 동적 메모리 할당 오버헤드와
가비지 컬렉션(GC)을 줄일 수 있습니다.
- 게임이란 도중에 렉이 걸리는 것보단, 로딩이 오래 걸리는 것이 유저 경
험에 있어서 더욱 이롭습니다.
Object Pooling01
10
1. 오브젝트 생성 시 요구되는 높은 비용을 피하기 위해.
2. 빠른 객체의 초기화 속도
3. 적은 오브젝트의 수로도 많은 오브젝트를 표현할 수 있는점.
4. GC로 인한 프레임 드랍 회피.
Object Pooling 사용하는 이유02
11
1. 객체를 빈번하게 생성/삭제하는 경우
2. 객체를 힙에 생성하기가 느리거나, 메모리 단편화가 우려되는 경우
3. 오브젝트 생성과 삭제함에 있어 병목현상이 발견되는 경우
ex) 게임을 표현함에 있어 많은 오브젝트가 필요한 경우
4. 데이터베이스/네트워크 연결처럼 접근 비용이 비싸면서 재사용 가능
한 자원을 객체가 캡슐화 할 때
Object Pooling 사용하면 좋은 예02
12
- 메모리 낭비 가능성
- 사용 가능 객체 개수가 정해져 있을 경우
- 객체를 위한 메모리 크기가 고정되어 있습니다.
1. 메모리 풀에 들어갈 수 있는 객체가 다양할 경우, 가장 큰
자료형에 맞춰야 합니다.
2. 그러므로 객체 크기 별로 풀을 나누는게 좋습니다.
- GC와의 충돌에 주의해야 합니다.
Object Pooling 주의할 점02
13
- 사용한 오브젝트를 풀에 반환 할 때 꼭 해당 객체를 초기화 해줘야
합니다.
- 사용 용도에 따라 오브젝트 풀을 어떻게 사용할 것인지에 대한
전략을 잘 세워야 합니다.
Object Pooling 주의할 점02
14
- 다른 목적으로 사용할 가용 힙 메모리의 양이 줄어든다. 따라서 현재 막
생성한 풀 외에도 메모리를 계속 할당한다면, 가비지 컬렉션이 더욱 자주
실행될 수 있습니다.
- 가비지 컬렉션에 걸리는 시간은 살아있는 오브젝트의 수에 비례하여
증가하기 때문에 매번 더 느려질 수 있습니다.
- 너무 큰 풀을 할당하거나 풀에 있는 오브젝트가 한동안 필요가 없는 상
황에서 풀을 활성화하여 유지한다면, 성능에 지장이 생기게 됩니다.
Object Pooling 단점02
15
- 즉, 오브젝트 풀 오버헤드(오브젝트 풀을 사용하지 않았을 때 생기는 메
모리 부하)인 경우에만 사용해야 이득을 볼 수 있다.
- 지속적인 프로파일링을 통해 이득인지 실인지 잘 따져봐야 할 것입니
다.
Object Pooling 단점02
16
실습
언리얼 엔진을 통한 오브젝트 풀링 실습
오브젝트 풀링 실습03
18
오브젝트 풀링 실습03
19
ObjectWithinPool
Actor
오브젝트 풀에 담을
클래스
활성/비활성화 기능
담당
SpawnObjects
Actor
실제 생성되 레벨에
배치될 오브젝트
이번 실습에서는 플
레이할 캐릭터와 같
은 오브젝트를 배치
할 예정입니다.
ObjectPool
ActorComponent
오브젝트 풀을 담당
할 컴포넌트
액터를 미리 생성해
놓고, 액터를 반환
해줄 기능을 담당
ObjectWithinPool에
서 사용
- 풀에 담을 오브젝트를 컨트롤할 액터
클래스를 생성합니다.
- 활성/비활성이 가능하도록 멤버 변수
및 함수 생성 합니다.
- 일정 시간이 지나면 오브젝트를 자동으
로 비활성화 해주도록 액터의
SetLifeSpan을 오버라이드합니다.
실습03
20
실습03
21
- ObjectWithinPool 액터에 오브젝트 풀링 기능을 담당할 ActorComponent클래스
를 생성합니다.
- 정의할 기능으로는
1. 풀에서 오브젝트를 꺼내오는 기능
2. 오브젝트 풀에 담을 클래스 정의
3. 풀 사이즈만큼 오브젝트를 저장해놓을 Tarray를 정의.
실습03
22
실습03
23
실습03
24
- 실제 생성될 오브젝트를 정의합니다.
- BoxComponent를 RootComponent로 사용하기
위해 정의했습니다.
- 오브젝트 풀에서 오브젝트를 가져오기 위해
ObjectPool 객체를 선언하였습니다.
- 생명주기를 엔진에서 컨트롤 할 수 있도록
LifeSpan, SpawnCooldown을 UPROPERTY로, 그
리고 스폰 주기를 체크할 Timer를 선언했습니다.
- 생성할 때 사용할 함수 Spawn()을 선언해주었습
니다.
실습03
6
실습03
26
실습03
27
- ObjectWithinPool 클래스와 SpawnObject를
사용하기 위해 C++클래스를 블루프린트 클래
스로 생성해주었습니다.
실습03
28
- 캐릭터와 똑같은 모습
을 보여주기 위해
SkeletalMesh 컴포넌트
를 추가해서 캐릭터를
표현하고, 애니메이션
블루프린트를 추가해
Idle모션을 추가해주었
습니다.
- 정면을 바라볼 수 있
도록 Rotation Z축을 -90
도로 변경해주었습니다.
실습03
29
- 마지막으로 만들어놨던 SpawnObject 블루프
린트를 월드에 배치해줍니다.
- C++에서 ObjectPool ActorComponent를 생성
해줬기 때문에 디테일 패널에 추가가 되있는 것
을 볼 수 있습니다.
- 좀 더 빠른 재생성을 보여드리기 위해
LifeSpan과 Spawn Cooldown의 값을 일부 조절
했습니다.
결과03
6
마무리
총정리
- 오브젝트 풀링의 구현 방법은 게임마다, 또는 상황마다 상이하므로 때
에 맞춰 구현하시면 됩니다.
- 핵심은 이미 있는, 또는 미리 만들어 놓은 오브젝트를 재사용함으로써
오브젝트 생성과 삭제의 오버헤드를 피한다는 것입니다.
- 다시 한번 강조 드리지만 무조건적인 오브젝트 풀링 방법의 채용은 좋
은 방법은 아닙니다.
- 언제나 지속적인 프로파일링을 통해 필요한 요소에 최적의 풀링 개수
를 선택해서 적용하는 것이 가장 좋은 방법입니다.
마무리04
32
참고 자료04
33
- https://www.slideshare.net/agebreak/ss-75060410
[게임메카닉스] 유니티 오브젝트 풀링 구현하기
- https://www.slideshare.net/agebreak/unite2015-47100325
[Unite2015] 유니티 최적화 테크닉 총정리
- https://glikmakesworld.tistory.com/13
- https://nogan.tistory.com/7
- https://www.youtube.com/watch?v=g4pAO01FFlQ
- https://en.wikipedia.org/wiki/Object_pool_pattern
- https://github.com/TonyChoiMS/OpenWorldTutorial
감사합니다

언리얼을 활용한 오브젝트 풀링

  • 1.
  • 2.
  • 3.
  • 4.
    게임을 개발함에 있어서인스턴스의 생성과 삭제는 굉장히 빈번하게 일 어나게 됩니다. 오브젝트 생성과 삭제01 4
  • 5.
    인스턴스의 생성과 삭제는매우 무거운 작업입니다. 동적으로 생성된 인스턴스는 힙 메모리에 할당되고, 해당 메모리를 다시 해제해줘야하는 작업을 해야하기 때문이죠. 오브젝트 생성과 삭제01 5
  • 6.
    - 오브젝트의 잦은생성과 삭제는 메모리 단편화 문제가 생기게 됩니다. * 외부 메모리 단편화 오브젝트 생성과 삭제01 6
  • 7.
    - 오브젝트 풀링은이러한 문제들을 해결하기 위해 사용되고 있습니다. 오브젝트 생성과 삭제01 7
  • 8.
  • 9.
    - 디자인 패턴의일종(객체 풀[Object Pool]) - 짧게 사용하고 사라진 뒤에 다시 사용하는 오브젝트의 경우 매번 다시 생성/해제를 반복하게 되면 메모리 부하가 심해집니다. - 객체를 매번 할당, 해제하지 않고 고정 크기 풀에 들어 있는 객체를 재 사용함으로써 메모리 사용 성능을 개선합니다. - 메모리 단편화를 방지합니다. Object Pooling02 9
  • 10.
    - 화면에 보이지않게만 하고(Deactive) 메모리를 해제하지 않은 채로 필 요할 때마다 다시 사용하는 기법 - 메모리 할당을 더 간단하게 할 수 있고, 동적 메모리 할당 오버헤드와 가비지 컬렉션(GC)을 줄일 수 있습니다. - 게임이란 도중에 렉이 걸리는 것보단, 로딩이 오래 걸리는 것이 유저 경 험에 있어서 더욱 이롭습니다. Object Pooling01 10
  • 11.
    1. 오브젝트 생성시 요구되는 높은 비용을 피하기 위해. 2. 빠른 객체의 초기화 속도 3. 적은 오브젝트의 수로도 많은 오브젝트를 표현할 수 있는점. 4. GC로 인한 프레임 드랍 회피. Object Pooling 사용하는 이유02 11
  • 12.
    1. 객체를 빈번하게생성/삭제하는 경우 2. 객체를 힙에 생성하기가 느리거나, 메모리 단편화가 우려되는 경우 3. 오브젝트 생성과 삭제함에 있어 병목현상이 발견되는 경우 ex) 게임을 표현함에 있어 많은 오브젝트가 필요한 경우 4. 데이터베이스/네트워크 연결처럼 접근 비용이 비싸면서 재사용 가능 한 자원을 객체가 캡슐화 할 때 Object Pooling 사용하면 좋은 예02 12
  • 13.
    - 메모리 낭비가능성 - 사용 가능 객체 개수가 정해져 있을 경우 - 객체를 위한 메모리 크기가 고정되어 있습니다. 1. 메모리 풀에 들어갈 수 있는 객체가 다양할 경우, 가장 큰 자료형에 맞춰야 합니다. 2. 그러므로 객체 크기 별로 풀을 나누는게 좋습니다. - GC와의 충돌에 주의해야 합니다. Object Pooling 주의할 점02 13
  • 14.
    - 사용한 오브젝트를풀에 반환 할 때 꼭 해당 객체를 초기화 해줘야 합니다. - 사용 용도에 따라 오브젝트 풀을 어떻게 사용할 것인지에 대한 전략을 잘 세워야 합니다. Object Pooling 주의할 점02 14
  • 15.
    - 다른 목적으로사용할 가용 힙 메모리의 양이 줄어든다. 따라서 현재 막 생성한 풀 외에도 메모리를 계속 할당한다면, 가비지 컬렉션이 더욱 자주 실행될 수 있습니다. - 가비지 컬렉션에 걸리는 시간은 살아있는 오브젝트의 수에 비례하여 증가하기 때문에 매번 더 느려질 수 있습니다. - 너무 큰 풀을 할당하거나 풀에 있는 오브젝트가 한동안 필요가 없는 상 황에서 풀을 활성화하여 유지한다면, 성능에 지장이 생기게 됩니다. Object Pooling 단점02 15
  • 16.
    - 즉, 오브젝트풀 오버헤드(오브젝트 풀을 사용하지 않았을 때 생기는 메 모리 부하)인 경우에만 사용해야 이득을 볼 수 있다. - 지속적인 프로파일링을 통해 이득인지 실인지 잘 따져봐야 할 것입니 다. Object Pooling 단점02 16
  • 17.
    실습 언리얼 엔진을 통한오브젝트 풀링 실습
  • 18.
  • 19.
    오브젝트 풀링 실습03 19 ObjectWithinPool Actor 오브젝트풀에 담을 클래스 활성/비활성화 기능 담당 SpawnObjects Actor 실제 생성되 레벨에 배치될 오브젝트 이번 실습에서는 플 레이할 캐릭터와 같 은 오브젝트를 배치 할 예정입니다. ObjectPool ActorComponent 오브젝트 풀을 담당 할 컴포넌트 액터를 미리 생성해 놓고, 액터를 반환 해줄 기능을 담당 ObjectWithinPool에 서 사용
  • 20.
    - 풀에 담을오브젝트를 컨트롤할 액터 클래스를 생성합니다. - 활성/비활성이 가능하도록 멤버 변수 및 함수 생성 합니다. - 일정 시간이 지나면 오브젝트를 자동으 로 비활성화 해주도록 액터의 SetLifeSpan을 오버라이드합니다. 실습03 20
  • 21.
  • 22.
    - ObjectWithinPool 액터에오브젝트 풀링 기능을 담당할 ActorComponent클래스 를 생성합니다. - 정의할 기능으로는 1. 풀에서 오브젝트를 꺼내오는 기능 2. 오브젝트 풀에 담을 클래스 정의 3. 풀 사이즈만큼 오브젝트를 저장해놓을 Tarray를 정의. 실습03 22
  • 23.
  • 24.
  • 25.
    - 실제 생성될오브젝트를 정의합니다. - BoxComponent를 RootComponent로 사용하기 위해 정의했습니다. - 오브젝트 풀에서 오브젝트를 가져오기 위해 ObjectPool 객체를 선언하였습니다. - 생명주기를 엔진에서 컨트롤 할 수 있도록 LifeSpan, SpawnCooldown을 UPROPERTY로, 그 리고 스폰 주기를 체크할 Timer를 선언했습니다. - 생성할 때 사용할 함수 Spawn()을 선언해주었습 니다. 실습03 6
  • 26.
  • 27.
    실습03 27 - ObjectWithinPool 클래스와SpawnObject를 사용하기 위해 C++클래스를 블루프린트 클래 스로 생성해주었습니다.
  • 28.
    실습03 28 - 캐릭터와 똑같은모습 을 보여주기 위해 SkeletalMesh 컴포넌트 를 추가해서 캐릭터를 표현하고, 애니메이션 블루프린트를 추가해 Idle모션을 추가해주었 습니다. - 정면을 바라볼 수 있 도록 Rotation Z축을 -90 도로 변경해주었습니다.
  • 29.
    실습03 29 - 마지막으로 만들어놨던SpawnObject 블루프 린트를 월드에 배치해줍니다. - C++에서 ObjectPool ActorComponent를 생성 해줬기 때문에 디테일 패널에 추가가 되있는 것 을 볼 수 있습니다. - 좀 더 빠른 재생성을 보여드리기 위해 LifeSpan과 Spawn Cooldown의 값을 일부 조절 했습니다.
  • 30.
  • 31.
  • 32.
    - 오브젝트 풀링의구현 방법은 게임마다, 또는 상황마다 상이하므로 때 에 맞춰 구현하시면 됩니다. - 핵심은 이미 있는, 또는 미리 만들어 놓은 오브젝트를 재사용함으로써 오브젝트 생성과 삭제의 오버헤드를 피한다는 것입니다. - 다시 한번 강조 드리지만 무조건적인 오브젝트 풀링 방법의 채용은 좋 은 방법은 아닙니다. - 언제나 지속적인 프로파일링을 통해 필요한 요소에 최적의 풀링 개수 를 선택해서 적용하는 것이 가장 좋은 방법입니다. 마무리04 32
  • 33.
    참고 자료04 33 - https://www.slideshare.net/agebreak/ss-75060410 [게임메카닉스]유니티 오브젝트 풀링 구현하기 - https://www.slideshare.net/agebreak/unite2015-47100325 [Unite2015] 유니티 최적화 테크닉 총정리 - https://glikmakesworld.tistory.com/13 - https://nogan.tistory.com/7 - https://www.youtube.com/watch?v=g4pAO01FFlQ - https://en.wikipedia.org/wiki/Object_pool_pattern - https://github.com/TonyChoiMS/OpenWorldTutorial
  • 34.