Pooling Objects

Going through Goetz's book Java Concurrency in Practice, he makes a case against using the object pool (section 11.4.7) - the main arguments are:

1) distribution in Java is faster than C malloc 2) threads requesting objects from the pool require expensive synchronization

My problem is not so much that distribution is slow, but that periodic garbage collection introduces outliers during the response, which can be eliminated by reducing object pools.

Are there any issues that I do not see when using this approach? Essentially, I split the pool of objects into threads ...

+4
source share
8 answers

If its stream is local, you can forget about it:

2) threads requesting objects from the pool require expensive synchronization

As a local thread, you do not need to worry about synchronization to fetch from the pool itself.

+2
source

In Java 1.4, object allocation was relatively expensive, so object pools for simple objects could help. However, in Java 5.0, object placement has improved significantly, but synchronization still made sense that object distribution is faster than synchronization. those. deleting object pools improves performance in many cases. In Java 6, synchronization has improved to such an extent that the object pool can slightly affect performance in simple cases.

Avoiding simple object pools is a good idea because it is simpler and not for performance reasons.

For more complex / larger objects, object pools can be useful in Java 6, even if you use synchronization. for example, a socket, file stream, or database connection.

+2
source

(sun) GC scans live objects. it is assumed that there are paths of more dead objects than living objects in a typical executable program of a Java program. he marks living objects and leaves the rest.

if you cache a lot of objects, they all live. and if you have several GB of such objects, the GC is going to spend a lot of time scanning them in vain. long pauses of GC can paralyze your application.

caching something just to make it not garbage does not help GC.

not to say that caching is wrong. if you have 15G memory and your database 10G, why not cache everything in memory, so the answers are quickly covered. note that this is caching something that would otherwise be slow to fetch.

in order to prevent fruitless scans of the 10G cache, the cache must be out of GC control. For example, use "memcached", which lives in a different process, and has its own cache optimized GC.

the latest news is Terracotta BigMemory, which is a pure Java solution that does similar.


An example of a local thread pool is the direct ByteBuffer pool. when we call

channel.read(byteBuffer) 

if byteBuffer is not β€œdirect,” β€œdirect” should be highlighted under the hood, which is used to exchange data with the OS. in a network application, such distributions can be very frequent, it seems that this is a waste in order to discard the just allocated and immediately select the other in the next statement. Sun engineers, apparently, do not really trust GC, created a stream of local pool of "direct" ByteBuffers.

+2
source

I think your case is a reasonable situation for using a pool. There is no evil in the union, Goetz means that you should not use it when it is not needed. Another example is pooling, because creating a connection is very expensive.

0
source

If it is threadlocal, it is very likely that you might not even need a join. Of course, this will depend on the use cases, but most likely in this thread you will probably need only one object of this type at a given time.

However, the caveat with threadlocals is memory management. Note that threadlocal values ​​do not disappear easily until the thread that owns these threadlocals disappears. Therefore, if you have a large number of threads and a large number of threadlocals, they may contribute slightly to the use of used memory.

0
source

I would definitely try. Although it is now "generally known" that you do not need to worry about creating an object, there can actually be a lot of performance from using object pools and specific classes. For the file processing platform, I got 5% of reading performance from objects combining objects [].

So, try and make time for execution to see if you get anything.

0
source

Even the old question, the point of two threads requesting objects from the pool, requires expensive synchronization, is not fully implemented.

It is possible to create a parallel (not synchronized) pool of objects that does not even demonstrate sharing (even false splitting) on ​​the fast path. In the simplified case, of course, each thread can have its own pool (more similar to a related object), but then such a greedy approach can lead to waste of resources (or hunger / error if the resource cannot be allocated)

Pools are good for heavy objects such as ByteBuffers, esp. direct, connections, sockets, streams, etc. In general, any objects that require intervention without java.

0
source

Joshua Bloch, in Effective Java (Second Edition), says:

The second advantage of static factory methods is that, unlike constructors, they are not required to create new ones each time they are called. This allows the use of immutable classes of pre-configured instances or cache when they are built and repeatedly abandon these cases so as not to create unnecessary duplicate objects. The Boolean.valueOf (boolean) method illustrates this method: it never creates an object. This method can significantly improve performance if equivalent objects are requested frequently, especially if these objects are expensive to create.

I would say it depends. If it's worth it, do it.

-2
source

All Articles