Understanding Object Pooling in Java: Commons Pool 2, Jedis, and HikariCP
This article explains how object pooling in Java—using Commons Pool 2, the Jedis Redis client, and the HikariCP database connection pool—can dramatically improve performance by reusing expensive resources, detailing key configuration parameters, benchmark results, and practical tuning advice.
In typical coding, expensive objects such as threads, database connections, or TCP connections are pooled to avoid costly creation and destruction.
Commons Pool 2
Commons Pool 2 provides a generic object pool implementation. The core class GenericObjectPool creates pools using a factory and configuration.
public GenericObjectPool(final PooledObjectFactory
factory, final GenericObjectPoolConfig
config)Case Study: Jedis
Jedis, a Redis client, uses Commons Pool to manage connections. The factory creates PooledObject instances wrapped in DefaultPooledObject . The pool stores idle objects in a LinkedBlockingDeque and uses parameters such as maxTotal , maxIdle , and minIdle to control size.
public PooledObject
makeObject() throws Exception {
Jedis jedis = null;
try {
jedis = new Jedis(jedisSocketFactory, clientConfig);
jedis.connect();
return new DefaultPooledObject<>(jedis);
} catch (JedisException je) {
if (jedis != null) {
try { jedis.quit(); } catch (RuntimeException e) { logger.warn("Error while QUIT", e); }
try { jedis.close(); } catch (RuntimeException e) { logger.warn("Error while close", e); }
}
throw je;
}
}Key Configuration Parameters
maxTotal : maximum number of objects in the pool.
maxIdle : maximum idle objects.
minIdle : minimum idle objects.
maxWaitMillis : maximum wait time for borrowing.
blockWhenExhausted : whether to block when the pool is exhausted.
Various test* flags control validation on create, borrow, return, and idle.
JMH Benchmark
A JMH benchmark comparing pooled Jedis versus direct Jedis shows roughly a 5× throughput improvement when using the pool.
@Fork(2)
@State(Scope.Benchmark)
@Warmup(iterations = 5, time = 1)
@Measurement(iterations = 5, time = 1)
@BenchmarkMode(Mode.Throughput)
public class JedisPoolVSJedisBenchmark {
JedisPool pool = new JedisPool("localhost", 6379);
@Benchmark
public void testPool() {
Jedis jedis = pool.getResource();
jedis.set("a", UUID.randomUUID().toString());
jedis.close();
}
@Benchmark
public void testJedis() {
Jedis jedis = new Jedis("localhost", 6379);
jedis.set("a", UUID.randomUUID().toString());
jedis.close();
}
}HikariCP Database Connection Pool
HikariCP is the default Spring Boot connection pool, optimized with FastList instead of ArrayList , byte‑code enhancements via Javassist, and a lock‑free ConcurrentBag , delivering superior performance.
Practical Advice
Set pool sizes according to workload (typically 20‑50 DB connections), configure timeouts, and monitor pool metrics to avoid resource exhaustion; similar principles apply to HTTP client pools, RPC pools, and thread pools.
Code Ape Tech Column
Former Ant Group P8 engineer, pure technologist, sharing full‑stack Java, job interview and career advice through a column. Site: java-family.cn
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.