ved_Rony
article thumbnail

ObjectPooling이란?

게임에 필요한 오브젝트를 미리 생성해서 필요할때마다 꺼내서 쓰고 사용이 끝나면, 다시 돌려놓는 개념이다.

필요할때마다, 오브젝트를 생성, 파괴를 하는 것이 아닌, 필요한만큼을 미리 만들어 두고 모자라면 추가 생성을 해주고, 게임이 끝나면 파괴를 해준다. 이로써, 생성 파괴 횟수를 줄일수있다.

 

언제 쓰이나?

주로, 총알이나 먼지 이펙트 같은곳에서 많이 쓰인다.

  • 객체를 빈번하게 생성/삭제 해야할때, 객체들의 크기가 비슷할 때
  • 객체를 힙에 생성하기엔 느리거나 메모리 단편화가 우려될 때
  • DB 연결이나 네트워크 연결같이 객체 생성시 비용이 비쌀 경우 미리 생성해두고 재사용할 필요가 있을 때

(메모리 단편화? RAM에서 메모리의 공간이 작은 조각으로 나뉘어져 사용가능한 메모리가 충분히 존재하지만 할당(사용)이 불가능한 상태 를 보고 메모리 단편화가 발생했다고 한다.)

추측 - 풀링을 하면 단편화가 일어난다 하더라도 이미 할당 해놓은 상태이기 때문에, 문제 없이 사용가능 할것이다.

 

왜 쓰나?

오브젝트를 생성하거나 파괴하는 작업은 꽤나 무거운 작업이다. 생성시, 필요한 메모리를 할당하고, 리소스를 로드하며, 파괴시 가비지 컬렉팅으로 인한 프레임 드랍이 생길수 있다.

(프레임 드랍? 처리 속도 이상의 처리가 올 경우 그 처리가 늦어져서 수직동기 신호를 놓쳐 화면의 갱신이 늦어지는 현상)

풀링하는 오브젝트의 리소스가 크다면 메모리 소비가 많을수도 있다. 그러니 리소스가 적은 총알 같은 작은 오브젝트를 풀링해준다. 이러한 작은 오브젝트는 쌓여서 느려진다고 해도 나중에 느려지는 편이며, 쌓이기 어려운 편이다. 하지만, 가비지 컬렉터로 인한 프레임 드랍은 생길수 있기에, 이를 해결하기 위한 방법으로 쓰인다. 또한, 생성/파괴 시 발생하는 오버헤드 방지도 가능하다

(가비지 컬렉터? 더 이상 쓰지 않는 메모리블락을 시스템이 자동으로 사용가능한 자원으로 회수하는 기능이다.)

(오버헤드란? 프로그램의 실행흐름 도중에 동떨어진 위치의 코드를 실행시켜야 할 때,예상하지 못하는 자원들이 소모되는 현상)

몇개~ 몇십 개까지의 오브젝트 숫자 정도에서는 큰 차이가 없다. 하지만, 오브젝트의 개수가 많아질수록 두 방식(생성/파괴 vs 풀링)에 따른 차이는 점점 벌어지게 된다.

물론, 메모리를 할당 해두기 때문에 메모리를 희생하여 성능을 높이는 것이지만, 실시간으로 작동하는 게임에서의 프레임 성능 때문에 오브젝트 풀링 방식이 자주 쓰이게 된다.

게임 플레이 할때 게임이 느려지는것보다, 처음 로딩 시간이 조금더 길어지는 것이 유저 입장에서 허용하기 쉽기 때문이다.

 

어떻게 써야하나?

풀클래스에 들어가는 객체는 사용상태인지 아닌지 상태를 나타내는 방법을 제공해야한다.

 

-풀은 초기화 될때, 객체들을 미리 생성해두고 사용안함 상태로 나타나야 한다.(setactive: false)

-새로운 객체가 필요할시 풀에 요청한다(ex: GetObj())

-풀은 사용가는 한 객체를 사용중으로 초기화하고 리턴한다

-객체를 사용하지 않을 시 사용안함 상태로 되돌린다.(ex: ReturnObj())

 

unity 구현방법

  1. 어디서든 접근가능 해야하므로 싱글톤으로 작성
  2. 어떠한 오브젝트를 미리 생성 후 활성화를 꺼줌(awake에서 미리 생성해주면 좋다)
  3. 그 오브젝트를 List같은 집합군에 넣어줌
  4. 그 오브젝트를 다른 스크립트에서 필요하면 사용하게끔 Get 함수를 만들어줌
  5. 필요한 곳에서 사용

주의! 객체를 재사용 하지만, 다른곳에 공유하지는 않는다. 한번에 한곳에서만 사용된다.

오브젝트 생성/파괴시 쓰레드에 나타나는 메모리 사용

풀링으로 오브젝트를 in&out하는 모습

profile

ved_Rony

@Rony_chan

검색 태그