[External] : Re: Virtual thread memory leak because TrackingRootContainer keeps threads
robert engels
rengels at ix.netcom.com
Mon Jul 22 22:24:00 UTC 2024
But even if VT threads are not GC roots, a GC root must have a reference to them, right? (to the Loom team) Otherwise they would be immediately collected.
If there is a reference to them, then that must follow up to a GC root (the static VT map), meaning that GC will still need to start from that root when tracing. I assume there could be low-level optimizations, where if a VT thread hasn’t run since the last GC, there is no need to follow it’s references because they could not have changed - but what if one of these references on its stack was a WeakReference? This would need clean-up since the clean-up handler might cause the VT or another to become Runnable.
TL;DR; It feels to me that VT threads not being GC roots doesn’t matter - as something must hold a strong reference - but I suspect I am missing something.
> On Jul 22, 2024, at 4:51 PM, Michal Domagala <outsider404 at gmail.com> wrote:
>
> Thanks for the explanation.
>
> I understand that paragraph
>
> "Unlike platform thread stacks, virtual thread stacks are not GC roots. Thus the references they contain are not traversed in a stop-the-world pause by garbage collectors, such as G1, that perform concurrent heap scanning"
>
> can be rewritten as
>
> "Some GC, such as G1, marks GC roots in stop-the-world pause. Unlike platform thread stacks, virtual thread stacks are not GC roots, therefore they do not impact stop-the-world pause."
>
> In my opinion, the current paragraph in JEP 444 requires readers to have a deep GC background. Usually, developers are not aware of GC root cost (at least I was not aware). Developers could tune the number of GC roots by changing the number of platform threads. Others, like static variables, are rather not tunable.
> But usually, the OS limits the number of platform threads much more strictly than GC performance.
>
> To sum up, JEP 444's message is: "Do not be afraid of the G1 initial mark phase when using virtual threads". But I think most developers, like me, never heard about it. Ohers, more advanced, could also never care about it, because Oracle docs says about the initial mark phase: "This phase is piggybacked on a normal (STW) young garbage collection.". I understand this sentence as the phase is "for free".
>
> To sum up again: when a developer like me reads that VT is not GC root, he does not see G1 profit behind. He reads: VT is GC'able. And the current state, when behavior is different, is misleading.
>
> sob., 13 lip 2024 o 14:57 Ron Pressler <ron.pressler at oracle.com <mailto:ron.pressler at oracle.com>> napisał(a):
>
>
> > On 11 Jul 2024, at 19:40, Michal Domagala <outsider404 at gmail.com <mailto:outsider404 at gmail.com>> wrote:
> >
> > Where is the mistake in my reasoning?
> >
>
> All objects in the heap, including virtual thread stacks, are traversed by the GC. GC *roots*, however, are things that some GCs, G1 in particular, traverse *in a stop-the-world-pause* while they don’t walk non-root objects in a STW pause but concurrently with the application running. Furthermore, roots are kept in memory even if there are no strong references to them, while normal objects are kept only if there are strong references to them.
>
> Virtual threads, unlike platform threads, are regular heap objects rather than roots. This makes a difference to *when* they are scanned by the GC, which has an impact on GC performance, especially as there can be lots and lots of virtual threads. Additionally, *if* there is no strong reference to the virtual thread, the GC may collect it, but I pointed out that usually there is a strong reference that is kept by default for observability purposes, but you can change that option so that such a reference is not kept.
>
> — Ron
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/loom-dev/attachments/20240722/6fed3645/attachment.htm>
More information about the loom-dev
mailing list