63

I am very familiar with the concept of object pooling and I always try to use it as much as possible.

Additionally I always thought that object pooling is the standard norm as I have observed that Java itself as well as the other frameworks use pooling as much as possible.

Recently though I read something that was completely new (and counter-intuitive?) to me.

That pooling actually makes program performance worse especially in concurrent applications, and it is advisable to instantiate new objects instead, since in newer JVMs, instantiation of an object is really fast.

I read this in the book: Java Concurrency in Practice

Now I am starting to think if I am missunderstanding something here since the first part of the book adviced to use Executors that reuse Threads instead of creating new instances.

So has object pooling become deprecated nowadays?

0

6 Answers 6

73

It is deprecated as a general technique, because - as you noticed - creation and destruction of short lived objects per se (i.e. memory allocation and GC) is extremely cheap in modern JVMs. So using a hand-written object pool for your run-of-the-mill objects is most likely slower, more complicated and more error-prone than plain new.*

It still has its uses though, for special objects whose creation is relatively costly, like DB / network connections, threads etc.

*Once I had to improve the performance of a crawling Java app. Investigation uncovered an attempt to use an object pool to allocate millions of objects... and the clever guy who wrote it used a single global lock to make it thread safe. Replacing the pool with plain new made the app 30 times faster.

8
  • 1
    So how can one decide if the instantiation of an object is too expensive?
    – user10326
    Oct 19, 2011 at 16:20
  • 3
    If the object consumes operating system resources (threads, I/O, shared memory, etc.) Oct 19, 2011 at 16:22
  • 13
    @user10326, by measurement :-) If creating your objects takes a looooong time, and/or they are associated with some special, potentially limited, non-memory resource, you may consider pooling. Oct 19, 2011 at 16:25
  • 8
    @user10326, IMO in over 95% of cases, the above criteria makes it easy to decide in advance whether you need an object pool. (Moreover, in almost all of the cases needing a pool, you will most likely use an existing library/framework, which probably has the object pool already implemented for you.) For the rest, it is still easy to hide object creation in e.g. a factory, which can be later reimplemented whichever way you see fit. Oct 19, 2011 at 16:38
  • 2
    Very important point made by @Peter Torok: many frameworks and libraries implement pooling for you, ALWAYS make sure that you are not already using a pooled library before implementing your own.
    – hromanko
    Oct 19, 2011 at 18:12
37

The answer to the concrete question: 'Is object pooling a deprecated technique?' is:

No. Object pooling is widely used in specific places - thread pooling, database connection pooling etc.

General object creation has never been a slow process. Pooling in itself consumes resources - memory and processing power. Any optimization is a trade-off.

The rule is:

Premature Optimization is Evil!!!

But when is a given optimization premature?

Premature optimization is any optimization done, before you have uncovered a bottleneck via thorough profiling.

3
  • 2
    Indeed. OP said "I always try to use it as much as possible" - this is the problem, IMO.
    – nerdytenor
    Oct 20, 2011 at 19:52
  • @Boris, So according to your second sentence, we should not object pool db connections and threads until we uncover them as a bottleneck via profiling?
    – Pacerier
    May 10, 2014 at 8:06
  • 1
    @Pac Some profiling results don't need constant re-measuring :-) Aug 28, 2015 at 2:48
9

Measure

It completely depends on your use case, size of your objects, your JVM, your JVM options, what GC you have enabled and a whole host of other factors.

In short: measure it before and measure it after. Assuming you're using an object pooling framework (like from Apache) then it shouldn't be too painful to swap between implementations.

Extra performance testing tip - let the JVM warm up a bit first, run the tests on a running JVM a number of times, it can behave differently.

4
  • 3
    "let the JVM warm up a bit first," -- I remember when the only thing that had to be "warmed up" was the monitor. Oy, everything new is old again.
    – kylben
    Oct 19, 2011 at 16:53
  • The only thing I need to warm up is the coffee! Sep 23, 2013 at 22:26
  • @Marijn, How do you let it "warm up"?
    – Pacerier
    May 10, 2014 at 8:07
  • See the JMH Framework for a full explanation (openjdk.java.net/projects/code-tools/jmh) but basically you've got to give the JVM a chance to JIT your code, run GC's before your benchmark & so on. May 12, 2014 at 7:54
9

In situations where you want to avoid garbage collection entirely, I think object pooling is the only viable alternative. So no, it is absolutely not a deprecated technique.

1
  • 1
    And I would add that it is a good idea to avoid GC whenever the objects are long-lived enough that they've moved into the older generation.
    – Zan Lynx
    Oct 19, 2011 at 23:54
9

That pooling actually makes program performance worse especially in concurrent applications, and it is advisable to instantiate new objects instead, since in newer JVMs, instantiation of an object is really fast.

Depends on the context.

1
  • 1
    Excellent answer, and cogent. I'd add (perhaps, maybe as an asterisk?) that the "24 bytes" claim refers to 4 instances of 4-byte floats (16 bytes), plus 4 bytes for the object reference, plus 4 bytes for a lock reference. This is the exact overhead your design eliminates.
    – strickli
    May 4, 2017 at 19:34
5

I do not know if there is a changing trend here but its certainly going to be the case that it depends. If your Java class is managing an external resource, such as an RMI connection or loading a resource file etc - then certainly the costs for object instantiation can still be high (though those resources may be pooled for you already!). As a general practice I'd agree with the book.

2
  • Well now I don't know.Because even in this case you describe which (before reading this) I would definetely use pooling, I would also have overhead.1)New constructs to handle the pooling 2) Synchronization for the getting/releasing object from pool 3) maintaining pool etc. So I am now thinking that perhaps there is no use case that it is useful except e.g. caching a socket instead of opening a new one each time to connect to the server.And this case is because of network latency and not instantiation creation overhead
    – user10326
    Oct 19, 2011 at 16:26
  • @user10326 Yes exactly. I see opening a socket as part of instantiation overhead, if its the class's job to do that and it must be initialized in the constructor then the latency & IO impacts are what you are concerned with.
    – Jeremy
    Oct 19, 2011 at 16:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.