Bump this thread again.

I really suffered from the use of Netty recyclers. It makes code much
really harder to maintain. I also made a benchmark and the recycler
allocation is 10~20x slower than a normal heap allocation.
https://gist.github.com/BewareMyPower/3dcc59183c92c76e9c985cced16d049d

I know it's hard to convince existing code that already uses the Netty
recycler. But I hope for new code, if you want to use a recycler,
please show the benefit rather than a simple "I think it reduces the
GC overhead (though I'm not sure if it's true, but it should be
true)". As a contrast, I can also say modern GC is much stronger than
you might think, especially for short-lived objects.

I believe the recycler was used everywhere just because the original
authors thought it would be good, without any real benchmark. I can
hardly see such tricks in other Java projects (e.g. Kafka). If you
know, feel free to share it.

Thanks,
Yunze



On Fri, Jun 28, 2024 at 11:10 AM Yunze Xu <x...@apache.org> wrote:
>
> Hi all,
>
> I'm doubting the value of the widely used Netty Recycler in Pulsar.
> When I checked the recent commits today, I found even a pair of
> Boolean and Integer is wrapped as a recyclable object. See
> TopicExistsInfo in https://github.com/apache/pulsar/pull/22838. It's
> really a mess, especially compared with a record implementation like:
>
> ```java
> public record TopicExistsInfo(boolean exists, int partitions) {}
> ```
>
> There was a similar doubt in an issue from early days in 2016:
> https://github.com/netty/netty/issues/5904. We can also see
> https://github.com/elastic/elasticsearch/pull/22452 from that issue
> that ES disables the Netty recycler by default. Yeah, Netty even
> provides a way to disable the recycler.
>
> I don't look into the implementation at the moment so I asked ChatGPT for now:
>
> ----
> Here are some cases when it is not recommended to use Netty Recycler:
> 1.Short-lived Objects: If objects in your application have very short
> lifecycles, meaning they are created and destroyed frequently and
> rapidly, using Recycler may add extra overhead as object pooling and
> reuse may not provide significant performance improvements.
> 2. High Thread Safety Requirements: If your application demands high
> thread safety for objects, and objects are passed between different
> threads frequently, using an object pool may introduce potential
> thread safety issues as object states are shared across threads.
> 3. Limited Memory Constraints: In some cases, object pools may consume
> additional memory, especially when a large number of objects need to
> be instantiated. If memory usage is a critical consideration, using an
> object pool may increase memory consumption.
> 4. Low Object Creation Cost: If the cost of creating objects is low,
> meaning object initialization overhead is minimal, and object reuse
> has little impact on performance, then using an object pool may not be
> worthwhile as the benefits of reuse may be offset by the management
> overhead of the object pool.
> ----
>
> At very least, it makes sense to me that short-lived objects and costs
> with low object creation. i.e. some simple tuple structures can be
> just implemented as a record. JVM GC is evolving and the recycling for
> such objects should not be high.
>
> Thanks,
> Yunze

Reply via email to