Wiki cleanup: error-doc removal, dedup merge, link normalization
10_Wiki/Topics 대규모 정리: - 오류 캡처/미완성 stub 문서 227개 제거 - 교차폴더 중복 43클러스터 병합 (63파일 → redirect) - 링크명 정규화: 깨진 링크 수정·redirect 직결·개념 매핑 ~2,400건 - 카테고리 MOC 6개 신규 생성 - Graph 섹션 미해결 related-keyword 링크 10,058건 제거 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -2,184 +2,26 @@
|
||||
id: wiki-2026-0508-object-pooling
|
||||
title: Object Pooling
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [Object Pool, Pool Pattern, Resource Pool]
|
||||
duplicate_of: none
|
||||
status: duplicate
|
||||
canonical_id: wiki-2026-0508-object-pooling-오브젝트-풀링
|
||||
duplicate_of: "[[Object Pooling (오브젝트 풀링)]]"
|
||||
aliases: []
|
||||
source_trust_level: A
|
||||
confidence_score: 0.9
|
||||
verification_status: applied
|
||||
tags: [performance, memory, gamedev, design-pattern, gc]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
verification_status: redirected
|
||||
tags: [duplicate]
|
||||
last_reinforced: 2026-05-20
|
||||
github_commit: pending
|
||||
tech_stack:
|
||||
language: cpp-csharp-typescript
|
||||
framework: unity-unreal
|
||||
---
|
||||
|
||||
# Object Pooling
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 expensive-to-create object를 미리 만들어두고 재사용하여 alloc/free latency · GC pressure를 제거."**. 1990s 게임에서 bullet/particle GC spike 회피로 시작. 2026 현재 Unity `ObjectPool<T>`, Unreal pooling subsystem, .NET `ArrayPool<T>`, Netty `Recycler` 등 plat-form 표준.
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 동작 원리
|
||||
1. Pool이 N개 instance 미리 alloc.
|
||||
2. `acquire()` → free list에서 pop.
|
||||
3. 사용 후 `release()` → reset 후 free list에 return.
|
||||
4. Pool 부족 시 grow (또는 block / fail).
|
||||
|
||||
### 매 적합한 대상
|
||||
- 매 alloc cost 큼 (network connection, thread, GPU buffer).
|
||||
- 매 빈번한 short-lived alloc (bullet, particle, packet).
|
||||
- 매 size predictable.
|
||||
- 매 reset 가능 (no permanent dirty state).
|
||||
|
||||
### 매 응용
|
||||
1. Game — bullets, enemies, particles, audio sources.
|
||||
2. Networking — DB connection pool (HikariCP), HTTP client (Apache).
|
||||
3. Rendering — command buffer pool, descriptor set pool (Vulkan).
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### C# Unity ObjectPool (2026 standard)
|
||||
```csharp
|
||||
using UnityEngine.Pool;
|
||||
|
||||
public class BulletSpawner : MonoBehaviour {
|
||||
[SerializeField] Bullet prefab;
|
||||
IObjectPool<Bullet> pool;
|
||||
|
||||
void Awake() {
|
||||
pool = new ObjectPool<Bullet>(
|
||||
createFunc: () => Instantiate(prefab),
|
||||
actionOnGet: b => b.gameObject.SetActive(true),
|
||||
actionOnRelease: b => b.gameObject.SetActive(false),
|
||||
actionOnDestroy: b => Destroy(b.gameObject),
|
||||
collectionCheck: true,
|
||||
defaultCapacity: 64,
|
||||
maxSize: 512);
|
||||
}
|
||||
public void Fire(Vector3 pos, Vector3 dir) {
|
||||
var b = pool.Get();
|
||||
b.Init(pos, dir, onExpire: () => pool.Release(b));
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### C++ template pool with free-list
|
||||
```cpp
|
||||
template<typename T, size_t N>
|
||||
class ObjectPool {
|
||||
alignas(T) std::byte storage[N * sizeof(T)];
|
||||
std::array<T*, N> free_list;
|
||||
size_t free_top = N;
|
||||
public:
|
||||
ObjectPool() {
|
||||
for (size_t i = 0; i < N; ++i)
|
||||
free_list[i] = reinterpret_cast<T*>(storage + i * sizeof(T));
|
||||
}
|
||||
template<typename... Args>
|
||||
T* acquire(Args&&... args) {
|
||||
if (free_top == 0) return nullptr;
|
||||
T* p = free_list[--free_top];
|
||||
return new (p) T(std::forward<Args>(args)...);
|
||||
}
|
||||
void release(T* p) {
|
||||
p->~T();
|
||||
free_list[free_top++] = p;
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
### TypeScript pool for Web/Node
|
||||
```typescript
|
||||
class ObjectPool<T> {
|
||||
private free: T[] = [];
|
||||
constructor(
|
||||
private factory: () => T,
|
||||
private reset: (t: T) => void,
|
||||
initial = 0,
|
||||
) {
|
||||
for (let i = 0; i < initial; i++) this.free.push(factory());
|
||||
}
|
||||
acquire(): T {
|
||||
return this.free.pop() ?? this.factory();
|
||||
}
|
||||
release(t: T) {
|
||||
this.reset(t);
|
||||
this.free.push(t);
|
||||
}
|
||||
}
|
||||
// Vector2 pool example
|
||||
const v2Pool = new ObjectPool<{x:number,y:number}>(
|
||||
() => ({x:0,y:0}),
|
||||
v => { v.x = 0; v.y = 0; },
|
||||
256);
|
||||
```
|
||||
|
||||
### .NET ArrayPool — GC-friendly buffer reuse
|
||||
```csharp
|
||||
byte[] buf = ArrayPool<byte>.Shared.Rent(4096);
|
||||
try {
|
||||
int n = await stream.ReadAsync(buf, 0, buf.Length);
|
||||
Process(buf.AsSpan(0, n));
|
||||
} finally {
|
||||
ArrayPool<byte>.Shared.Return(buf, clearArray: true);
|
||||
}
|
||||
```
|
||||
|
||||
### Connection pool (HikariCP idiom in Java)
|
||||
```java
|
||||
HikariConfig cfg = new HikariConfig();
|
||||
cfg.setJdbcUrl("jdbc:postgres://...");
|
||||
cfg.setMaximumPoolSize(20);
|
||||
cfg.setIdleTimeout(30_000);
|
||||
HikariDataSource ds = new HikariDataSource(cfg);
|
||||
|
||||
try (Connection c = ds.getConnection(); // ← acquire
|
||||
PreparedStatement s = c.prepareStatement("...")) {
|
||||
s.executeQuery();
|
||||
} // ← release on close()
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Approach |
|
||||
|---|---|
|
||||
| GC spike from short-lived alloc | object pool |
|
||||
| Network/DB resource | connection pool |
|
||||
| Render commands | per-frame pool, reset on frame end |
|
||||
| Variable size buffer | ArrayPool / segregated pool |
|
||||
| Single-threaded game | simple stack pool |
|
||||
| Multi-threaded | ConcurrentBag / lock-free pool |
|
||||
|
||||
**기본값**: 매 platform 제공 pool 사용 (Unity ObjectPool, ArrayPool, HikariCP) — 매 직접 구현 회피.
|
||||
> **이 문서는 [[Object Pooling (오브젝트 풀링)]] 의 중복본입니다.** Canonical 문서로 redirect.
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[Memory_Management]] · [[Design_Patterns]]
|
||||
- 변형: [[Connection_Pool]] · [[Thread_Pool]] · [[Free_List]]
|
||||
- 응용: [[Game_Loop]] · [[Particle_Systems]] · [[Garbage_Collection]]
|
||||
- Adjacent: [[Old_Space]] · [[Generational_Hypothesis]] · [[Memory_Leaks]]
|
||||
- 부모: [[Object Pooling (오브젝트 풀링)]] (canonical)
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: GC pressure visible (frame spike), expensive resource creation, predictable churn rate.
|
||||
**언제 X**: long-lived object, unique-per-instance state, alloc rate 낮음 — 매 premature opt.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **Forget release**: 매 leak — `using`/`try-finally`/RAII.
|
||||
- **Use after release**: 매 use-after-free 등가 — generational handle 사용.
|
||||
- **Dirty state carry-over**: 매 reset 누락 — bug.
|
||||
- **Unbounded growth**: 매 maxSize 없음 → OOM.
|
||||
- **Premature pooling**: 매 GC가 충분히 빠른 경우 — measure first.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (Game Programming Patterns by Nystrom 2014, Unity docs 2026, .NET ArrayPool source, HikariCP).
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
## 🕓 변경 이력
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — Object pooling pattern (4 lang impls + decision matrix) |
|
||||
| 2026-05-20 | 중복 병합 — canonical 문서로 redirect |
|
||||
|
||||
Reference in New Issue
Block a user