디자인 패턴 - 객체 풀(Object pool)

객체를 매번 할당, 해제하지 않고 고정 크기 풀에 들어 있는 객체를 재사용함으로써 메모리 사용 성능을 개선한다.

메모리 단편화를 방지한다. 게임이 실행될 때 메모리를 미리 크게 잡아놓고 쓴다.

재사용 가능한 객체들을 모아놓은 객체 풀 클래스를 정의한다.
여기에 들어가는 객체는 현재 자신이 '사용 중'인지 여부를 알 수 있는 방법을 제공해야 한다.
초기화될 때 사용할 객체들을 미리 생성하고(보통 같은 종류의 객체를 연속된 배열에 넣는다), 이들 객체를 '사용 안 함' 상태로 초기화한다.
새로운 객체가 필요하면 풀에 요청한다. 풀은 사용 가능한 객체를 찾아 '사용 중'으로 초기화한 뒤 반환한다. 객체를 더 이상 사용하지 않는다면 '사용 안 함' 상태로 되돌린다.
이런 식으로 메모리나 다른 자원 할당을 신경쓰지 않고 마음껏 객체를 생성, 삭제할 수 있다.

언제 쓰는가?

  • 객체를 빈번하게 생성/삭제
  • 객체들의 크기가 비슷
  • 객체를 힙에 생성하기가 느리거나, 메모리 단편화가 우려됨
  • 데이터베이스 연결, 네트워크 연결처럼 접근 비용이 비싸면서 재사용 가능한 자원을 객체가 캡슐화할 때
주의사항
  • 메모리 낭비 가능성
  • 사용 가능 객체 개수가 정해져 있다.
  • 객체를 위한 메모리 크기가 고정되어 있다. (가장 큰 자료형에 맞춰야 함)
    • 즉, 객체 크기 별로 풀을 나누는 게 좋다.
  • 초기화에 주의
  • GC와의 충돌에 주의

사용 가능한 객체를 찾기 위해 빈칸 리스트(Free list)를 고려해볼 수 있다.


객체가 풀과 커플링되는가?
 풀을 통해서만 객체를 생성하고자 하면 그렇게 하라. 사용 중인지 여부를 객체 내부에서 알아낼 수 있다.

그렇지 않다면?
 어떤 객체라도 풀에 넣을 수 있지만, 사용 중인지의 상태를 객체 외부에서 관리해야 한다.

객체 초기화 시 주의점은?
 객체를 풀 안에서 초기화한다면, 객체를 완전히 캡슐화 가능하다. 풀 클래스가 객체 초기화 때문에 복잡해진다.
 객체를 풀 바깥에서 초기화한다면, 풀의 인터페이스가 단순해진다. 외부 코드에서 객체 생성 실패 시의 처리를 할 수 있다.

댓글

이 블로그의 인기 게시물

디자인 패턴 - 더티 플래그(Dirty flag)

디자인 패턴 - 서비스 중개자 패턴(Service locator pattern)

인공지능 - 유한 상태 기계(Finite state machine)