<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"></head><body dir="auto"><div dir="ltr"></div><div dir="ltr">Put it another way for a reference to be enqueued it would require that the thread executed the finally block - which is not happening in this case. So you are observing an outcome that shouldn’t be possible given the semantics of try/finally and reachability. </div><div dir="ltr"><br><blockquote type="cite">On Aug 4, 2024, at 11:33 AM, robert engels <robaho@icloud.com> wrote:<br><br></blockquote></div><blockquote type="cite"><div dir="ltr"><meta http-equiv="content-type" content="text/html; charset=utf-8"><div dir="ltr"></div><div dir="ltr">I’m sorry that is not correct. There is still a reference to the object. The statements after the blocked statement clear the reference. There is nothing in the spec that states an infinitely blocked thread means all of the threads references are no longer valid and can be considered cleared. </div><div dir="ltr"><br></div><div dir="ltr">This is the exact reason Thread.stop() was deprecated as I shared. </div><div dir="ltr"><br></div><div dir="ltr">You simply can’t do this and create auditable systems - you are messing with program order and reachability guarantees. </div><div dir="ltr"><br><blockquote type="cite">On Aug 4, 2024, at 11:19 AM, Alex Otenko <oleksandr.otenko@gmail.com> wrote:<br><br></blockquote></div><blockquote type="cite"><div dir="ltr"><div dir="auto">I did. The statement that you copied means that no statement from the thread's code can be executed. Finalizer isn't part of that code.<div dir="auto"><br></div><div dir="auto">The finalizer section says that finalizer can be executed only after we can tell that no more actions to access the object can be performed. See, no notion of garbage, just that no further action can access it. Which is the case in the case of a hang.</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Sun, 4 Aug 2024, 17:08 robert engels, <<a href="mailto:robaho@icloud.com">robaho@icloud.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="auto"><div dir="ltr"></div><div dir="ltr">Did you read what you copied? It proves my point:</div><div dir="ltr"><br></div><div dir="ltr">“<span style="color:rgb(99,99,99);font-family:-apple-system-font;font-size:26px;background-color:rgb(255,255,255)"> In such cases, the actions generated by the blocked thread must consist of all actions generated by that thread up to and including the action that caused the thread to be blocked, and no actions that would be generated by the thread after that action.”</span></div><div dir="ltr"><br></div><div dir="ltr">Given that, the objects that were held can not be observed as being released - I.e. cannot placed in reference queues. </div><div dir="ltr"><br></div><div dir="ltr">So thank you, you provided the definitive answer that this ephemeral vt handling is not permitted. </div><div dir="ltr"><br></div><div dir="ltr"><br><blockquote type="cite">On Aug 4, 2024, at 7:17 AM, Alex Otenko <<a href="mailto:oleksandr.otenko@gmail.com" target="_blank" rel="noreferrer">oleksandr.otenko@gmail.com</a>> wrote:<br><br></blockquote></div><blockquote type="cite"><div dir="ltr"><div dir="auto"><p dir="ltr">> implementation</p>
<p dir="ltr">You said it :)</p>
<p dir="ltr">OK</p><p dir="ltr"><a href="https://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.4.9" target="_blank" rel="noreferrer">https://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.4.9</a> - non-termination</p><p dir="ltr"><a href="https://docs.oracle.com/javase/specs/jls/se7/html/jls-12.html#jls-12.6.2" target="_blank" rel="noreferrer">https://docs.oracle.com/javase/specs/jls/se7/html/jls-12.html#jls-12.6.2</a> - finalization<br></p><p dir="ltr">It all checks out, I think.</p></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Sun, 4 Aug 2024, 12:50 robert engels, <<a href="mailto:robaho@icloud.com" target="_blank" rel="noreferrer">robaho@icloud.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="auto"><div dir="ltr"></div><div dir="ltr">I can understand that reasoning but the problem is that it doesn’t align with current openjdk implementation. The observed behavior is the exact reason stop was deprecated with the exact same vulnerabilities. </div><div dir="ltr"><br><blockquote type="cite">On Aug 4, 2024, at 6:14 AM, Alex Otenko <<a href="mailto:oleksandr.otenko@gmail.com" rel="noreferrer noreferrer" target="_blank">oleksandr.otenko@gmail.com</a>> wrote:<br><br></blockquote></div><blockquote type="cite"><div dir="ltr"><p dir="ltr">I think the anguish may be coming from the GC / GC roots / finalizer behaviour being undefined. We'd all prefer things to be deterministic, but this one thing isn't.</p>
<p dir="ltr">So the solution is to not try and make a certain flavour of behaviour guaranteed, but to revisit our assumptions about the expected code behaviours. That some of our proofs of correctness may be based on implementation detail and not on real guarantees.</p>
<br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Sun, 4 Aug 2024, 12:05 robert engels, <<a href="mailto:robaho@icloud.com" rel="noreferrer noreferrer" target="_blank">robaho@icloud.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Avoiding was not the right word. Apologies. I only mean that I would like to understand the difference. I know it is at a know point vs arbitrary, but stop()could have been changed to only be at a safe point. Stop has an issue with possibly being in native code as well - but the deprecation justification doesn’t state any of this - only the stack unwinding which is the same issue that this capability in virtual thread has. <br>
<br>
> On Aug 3, 2024, at 7:00 PM, robert engels <<a href="mailto:robaho@icloud.com" rel="noreferrer noreferrer noreferrer" target="_blank">robaho@icloud.com</a>> wrote:<br>
> <br>
> Can you help me by stating why this is different than the thread stop?<br>
> <br>
> Because I think you could implement this by throwing a ThreadDeath - or as I suggested just reclaiming the memory. It feels like you are avoiding this issue for some reason.<br>
> <br>
>> On Aug 3, 2024, at 6:08 PM, Ron Pressler <<a href="mailto:ron.pressler@oracle.com" rel="noreferrer noreferrer noreferrer" target="_blank">ron.pressler@oracle.com</a>> wrote:<br>
>> <br>
>> <br>
>> <br>
>>>> On 2 Aug 2024, at 15:58, robert engels <<a href="mailto:robaho@icloud.com" rel="noreferrer noreferrer noreferrer" target="_blank">robaho@icloud.com</a>> wrote:<br>
>>> <br>
>>> Sorry to keep this thread going but in reviewing my test results I think this capability is now dangerous, as I related to the Thread.stop(). It is going to be the same issue.<br>
>>> <br>
>>> A lot of native resource backed objects have Java shadows with finalizers / reference queues. If the referenced are released without traveling up the stack the program/system can be in an inconsistent state.<br>
>>> <br>
>>> Take for instance a file system lock file that is removed on finalization. This would be removed allowing other processing to continue even though the locking process never completed nor rolled back.<br>
>>> <br>
>>> Maybe you could argue it is a bad design to do this but I think the pattern with Cleaners, etc is fairly pervasive.<br>
>>> <br>
>>> By releasing the objects program order guarantees are broken - I don’t think it is valid to do this - especially concerning try/finally.<br>
>>> <br>
>>> As I also said you could maybe be very tricky and just release the memory but that isn’t what is happening here. It is collecting the objects which allows side effects through finalization and reference queues.<br>
>> <br>
>> <br>
>> You are absolutely right that finalizers (and reference queues/cleaners in general) are a dangerous feature that should be avoided, but that’s the case regardless of thread collection, and even in the case of thread stacks, remember that references on the stack may be collected even if the thread is reachable, which is why ReachabilityFence exists. It is simply *not* the case, neither in theory nor in practice, that only references that have been popped off the stack are collected. That is *not* a guarantee, and if it's your assumption, then you’re in for some surprises and shouldn’t use finalizers/cleaners. In fact, the general advice is not to use these mechanisms at all. They don’t work as most people might assume they do.<br>
>> <br>
>> Having said all that, collecting a thread whose references are already allowed to be collected is valid.<br>
</blockquote></div>
</div></blockquote></div></blockquote></div>
</div></blockquote></div></blockquote></div>
</div></blockquote></div></blockquote></body></html>