Reputation: 27219
I have a Kotlin function with this signature:
fun registerDisposer(obj: Any, disposer: Closeable)
What the function does is attach disposer
to a phantom reference and arrange it to be closed when obj
is garbage-collected (i.e. when the phantom reference object is enqueued). The class of obj
is supposed to call it something like this:
class Holder(private val res1: Closeable, private val res2: Closeable) {
init {
registerDisposer(this, object: Closeable {
private val res1 = [email protected]
private val res2 = [email protected]
override fun close() {
res1.close()
res2.close()
}
})
}
}
(Let’s ignore whether this is a good idea to rely on this with general Closeable
s; the actual resource in question is a pointer managed by native/JNI code – I am trying to follow Hans Boehm’s advice. But all of this is not particularly relevant for this question.)
I am worried that this design makes it too easy to inadvertently pass an object that captures this
from the outer scope, creating a reference loop and preventing the object from being garbage-collected at all:
registerDisposer(this, Closeable {
this.res1.close()
this.res2.close()
})
Is there an annotation I can add to the disposer
parameter that will trigger a warning in this situation?
Upvotes: 0
Views: 262
Reputation: 27219
As of this writing, the answer seems to be: probably not.
It turns out a registerDisposer
function already exists as the register
method of java.lang.ref.Cleaner
, and it has no such annotation.
In Android, there is a similar annotation for android.os.AsyncTask
, but that simply warns at any anonymous object having AsyncTask
as its base class, whether it captures this
or not. (This makes sense in Java, where anonymous classes always capture this
, but not in Kotlin.)
Upvotes: 0