對象生命周期 = 創建 (T1) + 使用 (T2) + 清理 (T3)。
基準測試數據(相對單位):
創建開銷是方法調用的 166 倍,賦值的 980 倍。GC 清理雖自動但帶來:對象監控開銷 + Stop-The-World 停頓。高頻創建/銷毀是性能殺手。
緩存 + 共享:高頻對象用完不銷毀,歸還池中供下次復用。
效果:
適用場景:重量級對象(數據庫連接、線程、Socket、大數組、解析器、正則 Pattern)、高頻短命對象(數據庫連接池、線程池、HTTP 客戶端連接池)。
// 參數對象
class PoolConfig {
int minIdle, maxTotal;
// getter/setter
}
// 池化對象工廠(單例)
class PoolableFactory {
private static final PoolableFactory INSTANCE = new PoolableFactory();
public static PoolableFactory getInstance() { return INSTANCE; }
public T create(Class clazz) {
try { return clazz.getDeclaredConstructor().newInstance(); }
catch (Exception e) { throw new RuntimeException(e); }
}
public void destroy(Object obj) { /* 可選清理 */ }
}
// 對象池核心
class ObjectPool {
private final PoolConfig config;
private final Class type;
private final Deque pool = new ArrayDeque<>();
private int created = 0;
private final Object lock = new Object();
public ObjectPool(PoolConfig config, Class type) {
this.config = config; this.type = type;
// 預熱
for (int i=0; i
缺點:反射創建、類型轉換、全局鎖競爭、ArrayDeque 非線程安全需外部同步,性能受限。
// 以 StringBuffer 為例
class StringBufferPool {
private final StringBuffer[] pool;
private final AtomicInteger index = new AtomicInteger(-1);
private final int maxSize;
public StringBufferPool(int maxSize) {
this.maxSize = maxSize;
this.pool = new StringBuffer[maxSize];
for (int i=0; i= maxSize) {
index.set(maxSize - 1);
// 可選:自旋等待或擴容
LockSupport.parkNanos(100_000);
continue;
}
StringBuffer buf = pool[i];
if (buf != null) {
pool[i] = null;
buf.setLength(0); // 重置內容
return buf;
}
}
}
public void returnObj(StringBuffer buf) {
if (buf == null) return;
buf.setLength(0);
while (true) {
int i = index.decrementAndGet();
if (i < 0) {
index.set(0);
LockSupport.parkNanos(100_000);
continue;
}
if (pool[i] == null) {
pool[i] = buf;
return;
}
}
}
}
優化點:
setLength(0)),避免殘留數據泄露。ThreadLocal 本地緩存 + 全局池兩級架構,進一步降低競爭。GenericObjectPool、PoolableObjectFactory、驅逐策略、JMX 監控。對象池是「以空間換時間、以複雜度換性能」的經典權衡。用好它,先問:這個對象真的「重」嗎?真的「熱」嗎?真的值得池化嗎?