commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Peter Steijn" <pste...@gmail.com>
Subject [pool] Proposal: New Pool Impl -- GeneratorObjectPool
Date Sat, 01 Apr 2006 12:57:26 GMT
My name is Peter Steijn.  I am an undergraduate at the University of
Delaware, where I am working on an independent research project.  I have
been working on an optimization to object pooling upon which I have based a
new object pool implementation -- GeneratorObjectPool.  The following is
about the implemented changes to how object pooling works.

Before I go any further I would like to thank my faculty mentor, Professor
Phillip Conrad, for his insight and support.  I would also like to thank
apache contributor Sandy McArthur, who has spent the past few weeks
discussing my ideas, providing guidance and looking over my [sometimes
inane] attempts at coding.

You can access my objects at:  http://copland.udel.edu/~psteijn/apache/
  *GeneratorObjectPool.java -- the object pool implementation
  *GeneratorObjectPoolFactory.java -- basically GeneralObjectPoolFactory
  *TestGeneratorObjectPool.java -- JUnit tests modified to work with
GeneratorObjectPool, taken from TestGeneralObjectPool but modified because
of some changed assumptions in how some methods work (addObject in
particular).

GeneratorObjectPool changes the behavior of object pooling in the
borrowObject method.  Previous object pooling implementations, when
attempting to borrow an object from an empty pool, would create an object
for the requestor; blocking until the object was created and then returning
that object.  This is especially inefficient for object pooling, where the
objects you are creating are expected to be very expensive to create (read
http://www.theserverside.com/news/thread.tss?thread_id=37146 for an argument
on why you should only pool the heaviest of objects).  For example, creation
of a JDBC connection to a mysql database takes at least 25 milliseconds
(with virtually 0 latency) and seconds in even a minimally latent network.
In contrast to the creation of these objects, the act of borrowing, using
and returning the objects to the pool by a requestor usually takes less time
on the order of powers of ten.  Using a JDBC connection for an average query
can take as few as 5 milliseconds.  Using other objects that don't involve
sending data over a network would take even less time.

The observation that I am leading up to is this:
     Most likely the objects that are loaned out, making the pool empty for
your request (which is then going to sit there for up to seconds blocking
while your object is being made) are going to come back far before the
object you are creating would be ready.  The difference in time between the
first object that returns to the pool and when the requestor's object gets
created is avoidable blocking time.  In other words, we can save turn-around
time on requests which is what object pooling is all about!

GeneratorObjectPool does not block to create an object when a request hits
an empty pool.  Instead it schedules a TimerTask to run at the earliest time
possible.  This TimerTask creates an object and puts it into the pool.
While the TimerTask is running, the requestor is looking for any object to
return to the pool, not just the one that it asked to be created.  This is
done with a LinkedBlockingQueue (requires java 1.5.0_06 - there is a serious
bug in LinkedBlockingQueue in previous 1.5 releases [
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6215625], but I am also
planning to implement a version of GeneratorObjectPool that can run on java
1.3).

When hitting an empty object pool, the requestor should notice a very large
performance increase.  All other times the pool should not experience any
performance degradation.

Important issues to note:
-you can no longer assume that an additional object is in the pool directly
after calling the addObject method.  addObject only schedules an object to
be created and put into the pool.

I feel that I have justified why this optimization is necessary.  I look
forward to constructive criticism and any discussion of my ideas.

-Peter K. Steijn

PS - I have not done performance testing on my implementation yet, and have
only tested it on existing unit tests.  This is just to introduce my ideas
to the community.  The code is in no way guaranteed to be robust code.

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message