On Thu, 13 Oct 2022 23:03:56 GMT, John Hendrikx <[email protected]> wrote:
>> Also, using your example above, it might be too easy to create a memory leak
>> by inadvertently referring to a long lived object:
>>
>>
>> getSkinnable().textProperty().when(active).addListener((src,prev,current) ->
>> {
>> getSkinnable().setSomething(window.getSomething() + "..."); // window
>> reference makes the listener lambda uncollectable, resulting in a memory leak
>> });
>
>> Also, using your example above, it might be too easy to create a memory leak
>> by inadvertently referring to a long lived object:
>>
>> ```
>> getSkinnable().textProperty().when(active).addListener((src,prev,current) ->
>> {
>> getSkinnable().setSomething(window.getSomething() + "..."); // window
>> reference makes the listener lambda uncollectable, resulting in a memory leak
>> });
>> ```
>
> I'm not sure I follow your meaning. Why would referring to `window` make the
> lambda uncollectable? The lambda is referring to `window`, not the other way
> around.
>
> The current "alternative", which is weak listeners, is not what it is cracked
> up to be. A weak listener that is not strongly referenced will be collected
> at a random time, including never, (almost) immediately or in 5 minutes. All
> that time, the listener still functions, responds to potential events and
> property changes, even though the reason for its existence has since
> disappeared.
>
> When a weak reference is collected depends on many things, including the
> chosen GC, its parameters, JDK versions, memory pressure, etc. This proposal
> is specifically tailored to make the process of removing listeners
> deterministic without having to manually unregister listeners. Weak
> listeners are completely unpredictable and could potentially live much longer
> than expected on certain GC's (or future improvements of GC's) that have
> different strategies for cleaning weak references.
>
> A weak reference specifically is NOT something that gets cleaned up
> immediately upon the last reference disappearing. This can cause all kinds of
> phantom effects in JavaFX applications, if your listener does something like
> persisting state or printing something to the console. For example, a long
> lived model gets a weak listener attached to it when a dialog opens; the
> listener persists the last selected item. The dialog is closed and reopened.
> Now there might be two listeners, both persisting the last selected item.
> This may show up on your console as two database calls where one is expected.
>
> You can argue this is bad programming and that those listeners should have
> been cleaned up specifically with a dispose method, and I agree, you get
> predictable behavior that way. And that's exactly what this proposal also
> brings, predictable behavior, using a syntax that doesn't require you to keep
> track of your listeners explicitely:
>
>
> longLivedModel.indexProperty().when(dialog::shownProperty).addListener(persistPosition);
>
> This detaches the listener immediately after the dialog is closed. Not in 3
> seconds or 5 minutes, but as soon as it is no longer visible. Opening a new
> dialog will not reinstate this listener. Reusing the same dialog however
> would, and it would start working again exactly as you'd expect as soon as
> the dialog is visible again.
let me try to create a unit test (and I could be wrong, of course).
-------------
PR: https://git.openjdk.org/jfx/pull/830