Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it worth pooling byte[] and char[] arrays or is it better to just create

My code does a lot of Input/Output and this often involves the creation of temporary arrays to hold bytes or chars of some size - i often use 4096. Im starting to wonder - without actual tests - to verify if it would be better to pool these arrays. My code would change to something like this

take array from pool
try {
   read from one inputStream
   write to another outputstream using array
} finally {
   return array to pool
}
  • it is quicker to take or simply create a byte with 4096 which means some work is required to alloc mem on the heap, clear the 4096 bytes etc.
  • a pool seems simpler after all its probably just checking a list taking from the list and returning the array.

UPDATE I wrote a small program that did two things, created arrays and used an apache commons pool. Both looped a lot of times (100*100*100) and created/took, filled array, then released. I added a few goes in the beginning to warm up the jit and ignored the results of those. Each run ran the create and pool forms a dozen times, alternating between the two.

There was little difference between the pool and create forms. However if i added a clear array to the callback that is fired by apache commons pool when an instance is returned to a pool, the pool became that much slower thanthe created form.

like image 251
mP. Avatar asked Dec 21 '10 00:12

mP.


3 Answers

I would not implement pooling until a performance problem was demonstrated.

like image 79
Tony Ennis Avatar answered Nov 12 '22 16:11

Tony Ennis


Object pools add complexity to an application. In general, you have to deal with:

  • implementing the acquire / release operations in a thread-safe fashion,
  • ensuring that objects are always released, and are never retained / used after release,
  • making sure that released objects are "cleaned" before the next acquire, and
  • growing and shrinking the pool size.

If you make a mistake in the pool implementation, you can introduce insidious bugs.

Is it worth it? Well, the answer depends on the circumstances:

  • If memory is severely constrained, GC pauses are a major issue, and/or the cost of allocating and initializing an object is large, then probably yes.

  • If the cost of "cleaning" and object is roughly the same as the amortized cost of allocating a new one, then it is doubtful.

To understand the last point, you need to understand some basic copying GC ergonomics. Specifically if you:

  • assume a constant sized working set of reachable objects,
  • ignore object finalization and soft/weak/phantom references, and
  • increase the total heap size towards infinity,

then the amortized GC cost of allocating and reclaiming memory for object in Java approaches the cost of zeroing memory.

Thus, if the cost of cleaning an object is roughly equivalent to the GC overhead (zeroing) + the object constructor cost, then the only thing you gain by pooling is reducing the number of times the GC marking / copying occurs. But you can do the same thing by simply giving the application a larger heap.

like image 4
Stephen C Avatar answered Nov 12 '22 17:11

Stephen C


You could consider using the java.nio.Buffer classes. For example, you could have something like this:

class ReadWorker {
    private ByteBuffer buffer = ByteBuffer.allocate(4096);

    public void work() {
        fillBufferWithData();
        buffer.flip();
        doSomethingWithData();
        buffer.clear();
    }
}

Each call to work will clear the buffer ready for the next call but you won't be allocating/deallocating memory all the time. flip and clear are very fast operations.

Having one Buffer per worker will be easier than creating a pool with it's associated synchronisation fun-and-games.

EDIT: Note that I'm assuming you generate a fixed pool of workers so you're not creating new Buffer objects all the time.

If you can't have a fixed worker pool then you could consider creating a pool of Buffer objects rather than raw byte arrays. It depends on how you are using them.

like image 2
Cameron Skinner Avatar answered Nov 12 '22 16:11

Cameron Skinner