Tuesday 5 February 2008

Reusable object streams

In the process of profiling JBoss Cache internals prior to releasing another CR, I noticed that a lot of time was spent in the construction of ObjectOutputStreams and ObjectInputStreams. Especially wasteful since these streams are created for a very short while, just to be able to marshall an RPC method call to a byte buffer, to pass in to JGroups to replicate, or to unmarshall
a method call from a byte buffer on the other end.

Given that these streams have such a short life span, and are very frequently created and thrown away, pooling them is an obvious conclusion to come to. The problem is, JDK object streams make it very difficult to reset or reuse.

To overcome this, I have created my own set of streams - ReusableObjectOutputStream and ReusableObjectInputStream - that adds the ability to re-initialise the backing byte buffer. Which suddenly makes pooling possible. I can see why the JDK object streams do not allow reuse, since they could be backed by network streams that cannot be altered or reset, but in my case, since they are always backed by byte arrays, this is possible.

As far as JBoss Cache is concerned, I've had to add a few more configuration elements, with which to configure pool size and optimal default byte buffer size.

The code for these streams currently live in the JBoss Cache source tree. If there is any such use for such streams outside of JBoss Cache, let me know and perhaps I can package it as an independent library.

2 comments:

Manik Surtani said...

UPDATE: I'm currently investigating whether this is a good thing. People have reported class loader and memory leaks when using these reusable streams, possibly due to superclass java.io.ObjectInputStream's internal HandleTable which doesn't get cleared down.

Also investigating a better way to achieve reusable object streams.

Manik Surtani said...

I've disabled the pooled stream in JBC 2.1.1 and 2.2.0. Too many problems with class loader leaks. I still will investigate a better approach though, the cost of creating and throwing away these streams is not one I want to bear. :-)

See http://jira.jboss.org/jira/browse/JBCACHE-1336 if you want to track this.