<div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div>Thanks for the explanation.<br><br>I understand that paragraph</div><div><br></div><div>"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"</div><div><br></div><div>can be rewritten as</div><div><br></div><div>"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."</div><div><br></div><div>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.<br>But usually, the OS limits the number of platform threads much more strictly than GC performance.</div><div><br></div><div>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".</div><div><br></div><div>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.</div><div><br></div><div class="gmail_quote"><div dir="ltr" class="gmail_attr">sob., 13 lip 2024 o 14:57 Ron Pressler <<a href="mailto:ron.pressler@oracle.com">ron.pressler@oracle.com</a>> napisał(a):<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><br>
<br>
> On 11 Jul 2024, at 19:40, Michal Domagala <<a href="mailto:outsider404@gmail.com" target="_blank">outsider404@gmail.com</a>> wrote:<br>
> <br>
> Where is the mistake in my reasoning?<br>
> <br>
<br>
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.<br>
<br>
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.<br>
<br>
— Ron</blockquote></div></div></div></div></div>