Virtual thread memory leak because TrackingRootContainer keeps threads
Michal Domagala
outsider404 at gmail.com
Tue Jul 2 14:45:18 UTC 2024
I did research and I found that virtual threads are designed with the
rule that RAM is the limit. It means millions of virtual threads are OK.
And millions of GC roots is garbage collector death.
But it is a performance reason, not a "heart" reason. For me, the "heart"
reason is simplicity of use. I would like to use virtual thread in any
place in code when I want without overhead. For example, I can parallelize
computation using just ForkJoinPool. I would like to parallelize blocking
with the same simplicity.
One of Java's simplicity factors is the lack of destructor. When object
reference is lost, I do not care how resources are reclaimed. If VT is not
GC root, I can start as many as I want within - a potentially complex -
object and the system will reclaim resources when the object is GC'ed. If
VT is GC root, I must inspect each VT one by one and make sure they are
stopped.
It is called a destructor and destructor is not simple.
People wrote here that platform and virtual threads should be
interchangeable. They are interchangeable, because they have the same API.
Being GC root is not API - it is implementation.
wt., 2 lip 2024 o 02:37 Brian S O'Neill <bronee at gmail.com> napisał(a):
> I was confused when I first discovered that virtual threads could be
> GC'd when blocked with an infinite timeout. This was before the
> trackAllThreads option was enabled by default.
>
> If the virtual thread is blocked with an effectively infinite timeout
> (100 years), it won't be GC'd even when trackAllThreads is false. For
> consistency, I think it makes sense for virtual threads to never
> actually be GC'd except until after they exit.
>
> If you depended on virtual threads being GC'd when blocked with a real
> infinite timeout, then switching to platform threads would introduce a
> memory leak that didn't exist before. Ideally, the two thread types
> should be interchangeable.
>
>
> On 2024-07-01 12:08 PM, Michal Domagala wrote:
> > According to https://openjdk.org/jeps/444 <https://openjdk.org/jeps/444
> >,
> >
> > "Unlike platform thread stacks, virtual thread stacks are not GC roots."
> >
> >
> But jdk.internal.vm.ThreadContainers.RootContainer.TrackingRootContainer#VTHREADS
> keeps (hard) references to each virtual thread. Effectively,
> virtual threads are GC roots.
> >
> > I described full example here:
> >
> https://stackoverflow.com/questions/78596905/why-virtual-thread-is-not-garbage-collected-when-not-reachable
> <
> https://stackoverflow.com/questions/78596905/why-virtual-thread-is-not-garbage-collected-when-not-reachable
> >
> >
> > The problem was not visible since
> > https://bugs.openjdk.org/browse/JDK-8309406
> > <https://bugs.openjdk.org/browse/JDK-8309406>, because before the
> > change, VTHREADS "keep" was not enabled and i guess nobody cares memory
> > leak.
> >
> > But after the change every JVM is affected.
> >
> > A workaround for memory leak is set jdk.trackAllThreads=false
> >
> > Best regards
> > Michal Domagala
> >
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/loom-dev/attachments/20240702/c23d0ab5/attachment-0001.htm>
More information about the loom-dev
mailing list