views:

710

answers:

7
+6  Q: 

Object Pooling

What are the pro's and con's of maintaining a pool of frequently used objects and grab one from the pool instead of creating a new one. Something like string interning except that it will be possible for all class objects.

For example it can be considered to be good since it saves gc time and object creation time. On the other hand it can be a synchronization bottleneck if used from multiple threads, demands explicit deallocation and introduces possibility of memory leaks. By tying up memory that could be reclaimed, it places additional pressure on the garbage collector.

+9  A: 

Unless the object is expensive to create, I wouldn't bother.

Benefits:

  • Fewer objects created - if object creation is expensive, this can be significant. (The canonical example is probably database connections, where "creation" includes making a network connection to the server, providing authentication etc.)

Downsides:

  • More complicated code
  • Shared resource = locking; potential bottleneck
  • Violates GC's expectations of object lifetimes (most objects will be shortlived)

Do you have an actual problem you're trying to solve, or is this speculative? I wouldn't think about doing something like this unless you've got benchmarks/profile runs showing that there's a problem.

Jon Skeet
I am actually interested in lowering any blockages by say stop-the-world garbage collector in a latency sensitive real time application.
baskin
Well, you could look at real-time Java - I've never used it myself, but it would be worth checking. Try tuning the GC as well - there are lots of options there. Of course if you can make sure your code doesn't allocate *any* objects within the latency-sensitive bit, that's great - but hard.
Jon Skeet
Yes, I've looked at java RTS but am not inclined towards using it primarily because its not free. GC tuning also is something I've being trying out, especially playing around with CMS gc's. Its just that i'm not hitting the right optimal parameter combinations maybe. Thanks for all your help jon.
baskin
+1  A: 

I agree with Jon Skeet's points, if you don't have a specific reason to create a pool of objects, I wouldn't bother.

There are some situations when a pool is really helpful/necessary though. If you have a resource that is expensive to create, but can be reused (such as a database connection), it might make sense to use a pool. Also, in the case of database connections, a pool is useful for preventing your apps from opening too many concurrent connections to the database.

Andy White
+12  A: 

First law of optimization: don't do it. Second law: don't do it unless you actually have measured and know for a fact that you need to optimize and where.

Only if objects are really expensive to create, and if they can actually be reused (you can reset the state with only public operations to something that can be reused) it can be effective.

The two gains you mention are not really true: memory allocation in java is free (the cost was close to 10 cpu instructions, which is nothing). So reducing the creation of objects only saves you the time spent in the constructor. This can be a gain with really heavy objects that can be reused (database connections, threads) without changing: you reuse the same connection, the same thread.

GC time is not reduced. In fact it can be worse. With moving generational GCs (Java is, or was up to 1.5) the cost of a GC run is determined by the number of alive objects, not by the released memory. Alive objects will be moved to another space in memory (this is what makes memory allocation so fast: free memory is contiguous inside each GC block) a couple of times before being marked as old and moved into the older generation memory space.

Programming languages and support, as GC, were designed keeping in mind the common usage. If you steer away from the common usage in many cases you may end up with harder to read code that is less efficient.

David Rodríguez - dribeas
I am actually interested in lowering any blockages by say stop-the-world garbage collector in a latency sensitive real time application. What you say though makes a lot of sense and I do concur that benchmarks are necessary to take such a decision.
baskin
GC time *can* be reduced - if by using a pool you can avoid ever needing to allocate objects, for example, that could be a significant win in a low-latency app. It's a real pain to make sure you never allocate though...
Jon Skeet
(I agree that it could also very easily make the GC time worse, btw.)
Jon Skeet
It is a subtle issue. If objects end up being 'in between' (they survive the first GC and thus are moved) then it would be more expensive than having them allocated only once. But a design that really takes advantage of that fact would be hard and sensible to subtle problems.
David Rodríguez - dribeas
+4  A: 

Don't.

This is 2001 thinking. The only object "pool" that is still worth anything now a days is a singleton. I use singletons only to reduce the object creation for purposes of profiling (so I can see more clearly what is impacting the code).

Anything else you are just fragmenting memory for no good purpose.

Go ahead and run a profile on creating a 1,000,000 objects. It is insignificant.

Old article here.

Pat
+5  A: 

Pooling will mean that you, typically, cannot make objects immutable. This leads to defencive copying so you ultimately wind up making many more copies than you would if you just made a new immutable object.

Immutability is not always desirable, but more often than not you will find that things can be immutable. Making them not immutable so that you can reuse them in a pool is probably not a great idea.

So, unless you know for certain that it is an issue don't bother. Make the code clear and easy to follow and odds are it will be fast enough. If it isn't then the fact that the code is clear and easy to follow will make it easier to speed it up (in general).

TofuBeer
+1 for knowing my pain. I've just solved a serious data corruption bug by removing an object pool. Profiling on Java 1.3 and 1.4 showed the pool as being a big win, on 1.5 it slows the code down.
Darron
+2  A: 

It entirely depends on how expensive your objects are to create, compared to the number of times you create them... for instance, objects that are just glorified structs (e.g. contain only a couple of fields, and no methods other than accessors) can be a real use case for pooling.

A real life example: I needed to repetitively extract the n highest ranked items (integers) from a process generating a great number of integer/rank pairs. I used a "pair" object (an integer, and a float rank value) in a bounded priority queue. Reusing the pairs, versus emptying the queue, throwing the pairs away, and recreating them, yielded a 20% performance improvement... mainly in the GC charge, because the pairs never needed to be reallocated throughout the entire life of the JVM.

Varkhan
+1  A: 

Object pools are generally only a good idea for expensive object like database connections. Up to Java 1.4.2, object pools could improve performance but as of Java 5.0 object pools where more likely to harm performance than help and often object pools were removed to improve performances (and simplicity)

Peter Lawrey