<div dir="ltr">Thanks for valuable observability context<div><br></div><div>As I understand, initially VT created by Thread API was not observable in thread dump and VT created by Executors API was observable. It was confusing and now both kinds of VT are observable. Make sense.<br>But observability is reached by strong reference. VT created by Thread API are strongly referenced until stop and not GC'ed until stop and VT created by Executors API are not referenced at all and GC'ed when not reachable, regardless of being stopped or not. That's not OK and much worse than previous confusion. </div><div><br></div><div>It is not clear to me if strongly-referenced-VT-created-from-Thread-API is intentional or a mistake. Initially I thought it was a mistake caused by lack of awareness of the VT lifecycle. However, it is written that "GC'ing a thread that has not terminated will be very surprising to some developers. (...) is the expected behavior. Virtual threads started directly with the Thread API will be kept strongly reachable until they terminate."</div><div><br></div><div>In my understanding observability != strongly referenced. Current observability implementation, based on frail requirement that created-from-API VT should be present in thread dump as other VT, caused them to be strongly referenced, which is against JEP 444. </div><div><br></div><div>I am convinced that VT must not be strongly referenced, regardless of whether the API was used for creation. However, if the opposite decision is taken, it must be documented and published somewhere.</div><div><br></div><div>I would like to mention another clue that observability is implemented without VT knowledge. When <span style="font-family:"JetBrains Mono",monospace;color:rgb(8,8,8)">-Djdk.trackAllThreads=false, </span>observability is limited. Instead of strong references to VT (TrackingRootContainer#VTHREADS) there is counter: CountingRootContainer#VTHREAD_COUNT<br>Counter is increased by onStart() and decreased by onStop(). But some VTs are gone without onStop(), so the counter is not properly decreased.</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">wt., 9 lip 2024 o 09:50 Alan Bateman <<a href="mailto:Alan.Bateman@oracle.com">Alan.Bateman@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"><u></u>
<div>
On 08/07/2024 22:12, Michal Domagala wrote:<br>
<blockquote type="cite">
<div dir="ltr">
<div dir="ltr">Hi
<div><br>
</div>
<div>As a thread author, I would like to say I opened the
thread because I could not report a memory leak as a bug.
Page <a href="https://urldefense.com/v3/__https://bugreport.java.com/bugreport/submit_start__;!!ACWV5N9M2RV99hQ!O3-6Y8rB_Q3TnOXLeIa2WkhSm-X8hYgCkqwGAG4EqpVKaFgdKdh4kpH4juXWBBVbkBbMxFZDjRsTawE7Yeih$" id="m_-8751244382989946350m_3164609625677738720x_m_885626347485593257OWAfebd9909-0527-cccb-397c-37aae0d667d0" target="_blank">https://bugreport.java.com/bugreport/submit_start</a>
does not work.</div>
<div><br>
</div>
<div>In my understanding JEP 444 is finished and delivered in
JDK 21. Any deviation between JEP 444 and JDK 21 is a bug.<br>
I hoped somebody will say "OMG" and start fixing procedure.
But it seems to me discussion concerns on JEP 444 - good or
bad decision was taken.</div>
<div><br>
</div>
<div>Personally, I have high confidence in the written word.
Written word convinced me that VT is GC'ed. It's very
interesting to see other opinions, but in my understanding
the time is out of joint and seek for help to set it right</div>
</div>
</div>
<br>
</blockquote>
<br>
The topic you brought up was an open question when virtual threads
were a preview feature in JDK 19/20. For JDK 19/20, virtual threads
created directly with the Thread API were only only kept strongly
reachable when doing some operation that may continue (blocked on
I/O, timer, ...). This meant that, in some cases, "abandoned"
virtual threads could be GC'ed even though they had not terminated.<br>
<br>
The main thing that came up during the preview period was
observability. There were several questions here as to why virtual
threads created directly with the Thread API didn't show up in
thread dumps. It was surprising when virtual threads in other thread
groupings (e.g. Executors.newVirtualThreadPerTaskExecutor) did
appear in the thread dump. This was part of the motivation to change
things before virtual threads became a permanent feature (see the
History section of JEP 444).<br>
<br>
Aside from observability, the other issue is that GC'ing a thread
that has not terminated will be very surprising to some developers.
In many cases it will be transparent but there are cases where it is
more nuanced and can be observed in advanced usages. Finalization is
one topic. Another is Cleaner actions that may run while a resource
is in an inconsistent state.<br>
<br>
The summary is that the behavior you observe in JDK 21/22/23 is the
expected behavior. Virtual threads started directly with the Thread
API will be kept strongly reachable until they terminate. The thread
dump and other observability support can be used to identify
"abandoned" threads. This project has left the door open to the
possibility of introducing some notion of "ephemeral threads" in the
future. It would require quite a bit of exploration in several
areas, would have to be opt-in, and would also require Finalization
to be removed before introducing anything.<br>
<br>
-Alan<br>
</div>
</blockquote></div>