[External] : Re: Virtual thread memory leak because TrackingRootContainer keeps threads
Alex Otenko
oleksandr.otenko at gmail.com
Sun Aug 4 16:18:42 UTC 2024
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.
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.
On Sun, 4 Aug 2024, 17:08 robert engels, <robaho at icloud.com> wrote:
> Did you read what you copied? It proves my point:
>
> “ 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.”
>
> Given that, the objects that were held can not be observed as being
> released - I.e. cannot placed in reference queues.
>
> So thank you, you provided the definitive answer that this ephemeral vt
> handling is not permitted.
>
>
> On Aug 4, 2024, at 7:17 AM, Alex Otenko <oleksandr.otenko at gmail.com>
> wrote:
>
>
>
> > implementation
>
> You said it :)
>
> OK
>
> https://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.4.9
> - non-termination
>
> https://docs.oracle.com/javase/specs/jls/se7/html/jls-12.html#jls-12.6.2
> - finalization
>
> It all checks out, I think.
>
> On Sun, 4 Aug 2024, 12:50 robert engels, <robaho at icloud.com> wrote:
>
>> 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.
>>
>> On Aug 4, 2024, at 6:14 AM, Alex Otenko <oleksandr.otenko at gmail.com>
>> wrote:
>>
>>
>>
>> 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.
>>
>> 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.
>>
>> On Sun, 4 Aug 2024, 12:05 robert engels, <robaho at icloud.com> wrote:
>>
>>> 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.
>>>
>>> > On Aug 3, 2024, at 7:00 PM, robert engels <robaho at icloud.com> wrote:
>>> >
>>> > Can you help me by stating why this is different than the thread stop?
>>> >
>>> > 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.
>>> >
>>> >> On Aug 3, 2024, at 6:08 PM, Ron Pressler <ron.pressler at oracle.com>
>>> wrote:
>>> >>
>>> >>
>>> >>
>>> >>>> On 2 Aug 2024, at 15:58, robert engels <robaho at icloud.com> wrote:
>>> >>>
>>> >>> 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.
>>> >>>
>>> >>> 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.
>>> >>>
>>> >>> 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.
>>> >>>
>>> >>> Maybe you could argue it is a bad design to do this but I think the
>>> pattern with Cleaners, etc is fairly pervasive.
>>> >>>
>>> >>> By releasing the objects program order guarantees are broken - I
>>> don’t think it is valid to do this - especially concerning try/finally.
>>> >>>
>>> >>> 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.
>>> >>
>>> >>
>>> >> 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.
>>> >>
>>> >> Having said all that, collecting a thread whose references are
>>> already allowed to be collected is valid.
>>>
>>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/loom-dev/attachments/20240804/11f38e4d/attachment-0001.htm>
More information about the loom-dev
mailing list