Quick Flow
풀은 모든 allocation·GC·메모리 문제를 없애는 기능이 아니라, 반복 spawn/despawn의 allocation 빈도와 frame spike를 줄일 수 있는 재사용 정책입니다. pool에서 꺼낼 때 reset·activate하고, 반환할 때 listener·coroutine·particle·reference를 정리하며, 누가 반환·destroy·scene unload를 소유하는지 정합니다.
ObjectPool<Projectile> pool = new(
createFunc: CreateProjectile,
actionOnGet: p => p.OnGet(),
actionOnRelease: p => p.OnRelease(),
actionOnDestroy: p => Destroy(p.gameObject),
collectionCheck: true,
defaultCapacity: 32,
maxSize: 256);
Projectile projectile = pool.Get();
projectile.Launch(origin, direction, () => pool.Release(projectile));| 상황 | pool 정책 | 확인할 실패 |
|---|---|---|
| projectile·VFX·짧은 UI | reuse 후보 | reset 누락·double release |
| pool이 maxSize에 닿음 | destroy·drop·recycle 중 선택 | gameplay·visual 품질 영향 |
| scene unload | pool dispose owner 지정 | 반환 뒤 destroyed object 참조 |
| listener·coroutine 사용 | get/release에 등록·해제 | 이전 instance의 callback |
| 드문·수명 긴 object | 일반 생성도 검토 | pool이 복잡도만 늘림 |
get과 release의 계약
ObjectPool<T>는 createFunc, get/release/destroy callback, collectionCheck, capacity와 maxSize로 재사용을 관리합니다. collectionCheck는 같은 object를 두 번 release하는 실수를 개발 중 찾는 데 도움이 될 수 있고, maxSize를 넘는 반환 object는 destroy callback으로 처리됩니다. 실제 callback의 reset 범위는 type의 책임입니다.
OnGet에는 position·velocity·health·visual을 초기화하고 필요한 listener를 등록합니다. OnRelease에는 listener·coroutine·timer·target reference를 끄고 effect state를 정리합니다. gameObject.SetActive(false)만으로 C# event, static callback, async continuation이 자동 정리된다고 가정하지 않습니다.
성능과 소유권을 측정하기
pool도 createFunc가 새 object를 만들 때 allocation하고, closure·collection·native resource·asset loading은 별도의 allocation을 만들 수 있습니다. 풀을 도입하기 전후로 target device의 allocation count, GC allocation, frame-time spike, active/available count, memory를 Profiler에서 비교합니다. pool size를 미리 크게 잡으면 spike는 줄어도 memory가 늘 수 있습니다.
scene unload, cancel, object self-despawn 중 누가 Release를 정확히 한 번 부를지 정합니다. owner가 scene-local이면 scene 종료 때 pool 자체를 dispose하고, global pool이면 scene object reference를 빼지 않도록 asset·prefab lifecycle을 분리합니다. pool에 넣은 object가 다른 system의 parent나 event를 계속 잡고 있으면 재사용보다 leak가 먼저 문제가 됩니다.
풀을 쓰지 않을 때
보스, 화면 하나의 panel, 드물게 load하는 level object처럼 동시 수가 작고 reset이 복잡한 대상은 일반 생성이 더 명확합니다. pool을 쓰는 이유와 max exhaustion policy를 문서화하고, overload에서 object를 drop·recycle·expand할 때 사용자에게 어떤 현상이 보일지 test합니다.
풀의 성패는 Get이 아니라 Release에 있습니다. allocation을 줄였다는 추정만으로 완료하지 말고, 반환 횟수·상태 reset·scene 종료·frame time을 실제 profiler와 test로 확인하세요.
참고 링크
2 sources