The same happens in ARC code as well. People expect scope-based lifetimes and are surprised to learn about “last use” rules.
pjmlp
2 days ago
[ - ]
Those that don't keep up with WWDC talks are going to be even more surprised, given the changes on how ARC works across Swift versions.
Going back to finalizers, while they seemed a great idea since Smalltalk days, they have proven otherwise, and that is why nowadays they are largely deprecated.
In Java, and as of last Go's version, there are alternative ways with classical finalizers being "deprecated for removal" in Java's case, and on .NET SafeHandles and IDispose pattern is the way.
xxs
2 days ago
[ - ]
Java has had PhantomReferce for about 25y now. There are meant for post-mortrem clean up. (although both finalize and PhantomReferce are pre-mortrem, unlike WeakRefences)
One of the main issues with finalize method is that it adds the newly created objects (prior to invoking the c-tor) to a (effectively) global queue which has rather negative perf. impact. The happens-before semantics also work in a weird way, e.g. fields set in the c-tor may not be visible in finalize().
Finalize/clean up code is still needed to ensure proper freeing of non-managed 'objects'. They are more of a defense mechanism in most cases as close/dispose is the correct way.
immibis
2 days ago
[ - ]
PhantomReference solves the problem where objects can be resurrected during finalization, not the problem where objects can be finalized while you're still "using" them.
xxs
1 day ago
[ - ]
>finalized while you're still "using" them.
It's a well known way to deal with such cases by using an additional weak reference. (even I think J. Bloch has mentioned it). Here (typing w/o an other editor, excuse typos):
class X<T> extends PhantomRefenece<T> {
final WeakReference<T> weak;
X(T ref, ReferenceQueue<? super T> q){
super(ref, q);
this.weak = new WeakReference<>(ref);
}
}
...
for (X x; (x = (X)q.poll()) != null;) {
process(x.weak.get());
}
This is why a mentioned it is effectively pre-mortrem. PhantomReference still keeps the referent, it's just not possible to retrieve it as get() is overridden.
immibis
14 hours ago
[ - ]
Bad idea. Weak reference can be removed at the same time. You're supposed to let the PhantomReference contain the underlying thing that you want to delete when the object is GCed, such as a native handle.
zombot
1 day ago
[ - ]
Even orthography is trickier than one might think, as the title demonstrates.
Finalizers are tricker than you might think. Part 2
(sergeyteplyakov.github.io)
37 points
by: GOPbIHbI4
5 days ago
7 comments
saagarjha
2 days ago
[ - ]
The same happens in ARC code as well. People expect scope-based lifetimes and are surprised to learn about “last use” rules.
pjmlp
2 days ago
[ - ]
Those that don't keep up with WWDC talks are going to be even more surprised, given the changes on how ARC works across Swift versions.
Going back to finalizers, while they seemed a great idea since Smalltalk days, they have proven otherwise, and that is why nowadays they are largely deprecated.
In Java, and as of last Go's version, there are alternative ways with classical finalizers being "deprecated for removal" in Java's case, and on .NET SafeHandles and IDispose pattern is the way.
xxs
2 days ago
[ - ]
Java has had PhantomReferce for about 25y now. There are meant for post-mortrem clean up. (although both finalize and PhantomReferce are pre-mortrem, unlike WeakRefences)
One of the main issues with finalize method is that it adds the newly created objects (prior to invoking the c-tor) to a (effectively) global queue which has rather negative perf. impact. The happens-before semantics also work in a weird way, e.g. fields set in the c-tor may not be visible in finalize().
Finalize/clean up code is still needed to ensure proper freeing of non-managed 'objects'. They are more of a defense mechanism in most cases as close/dispose is the correct way.
immibis
2 days ago
[ - ]
PhantomReference solves the problem where objects can be resurrected during finalization, not the problem where objects can be finalized while you're still "using" them.
xxs
1 day ago
[ - ]
>finalized while you're still "using" them.
It's a well known way to deal with such cases by using an additional weak reference. (even I think J. Bloch has mentioned it). Here (typing w/o an other editor, excuse typos):
This is why a mentioned it is effectively pre-mortrem. PhantomReference still keeps the referent, it's just not possible to retrieve it as get() is overridden.immibis
14 hours ago
[ - ]
Bad idea. Weak reference can be removed at the same time. You're supposed to let the PhantomReference contain the underlying thing that you want to delete when the object is GCed, such as a native handle.
zombot
1 day ago
[ - ]
Even orthography is trickier than one might think, as the title demonstrates.