Performance Issues with Virtual Threads + ThreadLocal Caching in Third-Party Libraries (JDK 25)
Jianbin Chen
jianbin at apache.org
Sun Jan 25 06:11:27 UTC 2026
Hi Alan,
Thanks for the heads up — I’ll try running the performance tests again on
the JDK 26 EA build.
That said, let’s continue the discussion around the main topic of this
thread. I understand and largely agree with most people’s recommendations
and the reasons why virtual threads shouldn’t be pooled. However, those
recommendations generally assume that both our application and the
third‑party libraries it depends on have been adapted to newer JDK features
— for example, replacing ThreadLocal‑based buffer pools with proper object
pools — and I fully appreciate the benefits of making those changes.
In reality it’s often much harder: many third‑party libraries must remain
compatible with older JDK 8 users, so they are not eager to adopt newer
platform features. That leaves users like us in a difficult position. For
example, when JDK 21 shipped I eagerly adopted virtual threads, but then
suffered from issues caused by third‑party libraries using synchronized,
Object.wait, etc. I traced the pinned‑thread causes to such libraries —
take apache commons‑pool as an example: you can see PRs addressing
synchronized/Object.wait refactors here:
https://github.com/apache/commons-pool/pulls — some of those PRs were
opened two or three years ago and are still unapproved. Aren’t these kinds
of problems part of the motivation behind JEP 491?
Given this reality, the only practical short‑term approach available to me
appears to be a compromise: pool virtual threads but do not set a fixed
maximum thread count. That way I can both limit buffer waste (which hurts
performance) and still gain the throughput benefits of virtual threads.
Best regards,
Jianbin Chen
Alan Bateman <alan.bateman at oracle.com> 于2026年1月25日周日 00:42写道:
>
>
> On 24/01/2026 13:07, Jianbin Chen wrote:
> > Hi Alan,
> >
> > I ran my example on JDK 21 because it uses Thread.sleep. In an earlier
> > message on the mailing list I learned that virtual‑thread performance
> > on JDK 25 was worse for this kind of scenario compared with JDK 21,
> > and that the issue is supposed to be fixed in JDK 25.0.3 — which has
> > not been released yet.
>
> I assume this is about JDK-8370887 [1], which may be an issue in some
> usages but I don't think has come up in this thread. For your
> Thread.sleep benchmark then maybe you can try it with the JDK 26 EA
> builds [2] where you know that issue has been fixed. As I said, I think
> that benchmark will need a bit of work (esp. on warmup) to get useful data.
>
>
> >
> > That said, this does not affect the main point of my message: I’m
> > asking for advice about using pooled virtual threads to work around
> > third‑party libraries that implement buffer pools via ThreadLocal
> The advise is to not pool virtual threads. If a library is performing
> poorly because it assumes execution on a pooled thread then all we can
> suggest is to work with the maintainer of that library on the issue.
> Note that the JDK removed several usages of thread locals that were
> caching byte[] and other objects. That caching was beneficial a long
> time ago but not in recent recent/releases with significantly improved
> memory management and GC.
>
> -Alan
>
> [1] https://bugs.openjdk.org/browse/JDK-8370887
> [2] https://jdk.java.net/26/
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/loom-dev/attachments/20260125/f8d7c151/attachment.htm>
More information about the loom-dev
mailing list