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?

Jonas
  • 14,867
  • 9
  • 69
  • 102
user10326
  • 1,834
  • 3
  • 17
  • 18

6 Answers6

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.

Péter Török
  • 46,427
  • 16
  • 160
  • 185
  • 1
    So how can one decide if the instantiation of an object is too expensive? – user10326 Oct 19 '11 at 16:20
  • 3
    If the object consumes operating system resources (threads, I/O, shared memory, etc.) – kevin cline Oct 19 '11 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. – Péter Török Oct 19 '11 at 16:25
  • So one should design its classes and benchmark and then decide to use pooling?But this could require refactoring the whole code.It is usual to refactor the code, I just can not wrap my head that it would be acceptable to redesign the code to add in pooling that most people would consider it as sensible to have been considered in the original design steps – user10326 Oct 19 '11 at 16:28
  • 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. – Péter Török Oct 19 '11 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 '11 at 18:12
  • 1
    @user10326 RE: "_So one should design its classes and benchmark and then decide to use pooling? But this could require refactoring the whole code._" I really don't see how. I think you're making a mountain out of a (possibly non-existent) molehill. If you've designed your system to keep object creation as a separate concern in the first place, the refactoring should be trivial. Even if you haven't, switching 1 or 2 classes to use a pool shouldn't be too difficult. – Disillusioned Sep 23 '13 at 22:13
  • It is not a deprecated pattern. Only in languages that use Garbage Collectors particularly Java, Object pool could be a problem since it basically obstructs what garbage collection is doing; ie getting rid of dead object's memory whereas object pool tries to keep them alive. Object pool has may uses particularly in video games, where large objects like are constantly reused for a short period of time. It's a little tricky to implement but It is very useful in, indeed limited, applications. But calling it deprecated is simply wrong. – KeyC0de Sep 29 '19 at 09:28
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.

Boris Yankov
  • 3,573
  • 1
  • 23
  • 29
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.

Martijn Verburg
  • 22,006
  • 1
  • 49
  • 81
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.

Jer
  • 2,576
  • 1
  • 20
  • 17
  • 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 '11 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
    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 04 '17 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.

Jeremy
  • 4,609
  • 22
  • 22
  • 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 '11 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 '11 at 16:28