netty/netty — pull request #3069 by andreipet (2014-10-29 11:48:44+00:00)
Title: Recycler update

Statements made in commit: https://github.com/netty/netty/commit/580965f7753ad8aadc98e3d369499822ea2b7767 about an improved Recycler draw my attention.

Reviewing the code I did not see any improvement for the single thread
case. The improvement came from the fact that AbstractMicrobenchmark was
sending "-ea" as a startup argument for JVM and previous Recycler source
code had assertions trying to find out if an item is recycled already.
In fact from my testing I see a drop of performance around 20% in the
single thread scenario.

But the latest Recycler can now treat the multi thread scenario: one thread
gets a handle and another thread recycles the handle.
This scenario was not treated by the previous Recycler which dropped the
handle when recycled from another thread. So the pool was not working at
all in this scenario and can cause huge performance loss when elements
in pool are large (like 64KB buffers).

With current Recycler I saw some problems:
1. The "already recycled" exception is not triggered correctly or at
least as expected. I added a new test to prove this.
2. Strangely, the recycler keeps allocating new instances in a scenario
where 2 threads recycle the handles obtained for 1 thread. In the
classic 1 producer / 1 consumer scenario I did not see the problem. You
can see the problem in the new micro benchmark for the producer/consumer
scenario with 3 threads specified.
3. I think that each "recycler" thread (A) is now keeping a reference to
a stack from another thread (B), stack kept in a thread local. Even when
all condition are right for GC of thread B's thread local, the stack
will be referenced from thread A. Please search DELAYED_RECYCLED in
source code.

I suggest my version of Recycler because:
1. The "already recycled" exception thrown correctly.
2. Same performance as current Recycler for single thread and multi
thread scenario.
3. It can easily be improved by using another non-blocking collection
for sharing data between threads.

I don’t know how common the multi thread scenario is in netty. If it is
not common, I think a version using handles with a simple boolean value
(handle.inStack) will be enough.

This update alters 90% Recycler.java.
Adds a new @Test for Recycler and a new benchmark.
+Minor tweaks because the Handle is now non generic.

Thank you for your time and please excuse my poor english.