I have two questions regarding `Pinned` objects in...
# kotlin-native
j
I have two questions regarding
Pinned
objects in K/N. 1. If I pin an object using the
pin()
extension function and never
unpin()
it, will the garbage collector eventually collect it? I found a thread on this channel that suggests that a pinned object remains unchanged and is not moved or freed. However, I’ve written a test program that demonstrates that the callback passed to createCleaner is invoked for both the pinned value object and the Pinned -Object itself.
Copy code
@OptIn(ExperimentalNativeApi::class, ExperimentalForeignApi::class)
private fun allocate(): Unit {
    // create a dummy resource and pin it (but never unpin)
    val dummy = Any()
    val pinned = dummy.pin()

    // setup clean-up callbacks for both, the pinned value and the pinned-object
    createCleaner(dummy) {
        println("Cleaning up dummy (${markNow()})")
    }
    createCleaner(pinned) {
        println("Cleaning up pinned (${markNow()})")
    }
}

@OptIn(NativeRuntimeApi::class)
fun main() {
    allocate()
    // trigger garbage collection manually
    GC.collect()
    runBlocking {
        // wait 10 secs to see cleaner callbacks
        delay(10000)
    }
    println("Done. (${markNow()})")
}
This outputs
Copy code
Cleaning up pinned (ValueTimeMark(reading=15083))
Cleaning up dummy (ValueTimeMark(reading=129458))
Done. (ValueTimeMark(reading=10002954250))
So, according to this, the garbage collector actually recognizes both objects, implying that they are being freed. Is that accurate, or are those callbacks triggered even though the underlying object memory remains valid? 2. Assuming pinned is getting collected by the GC, will it
unpin()
the dummy object automatically?
n
have you fix that issue ?
j
No, I’m still not sure what’s happening under the hood. Perhaps memory remains valid even though the GC marks it for collection. Currently, I do something like
Copy code
var pinned = dummy.pin()
createCleaner(pinned) {
  it.unpin()
}
However, I’m not certain if this is a valid approach.
l
@Johannes Zottele is that inside a class? Otherwise
createCleaner
might not do what you expect. It calls the cleanup function when the
Cleaner
instance is collected, not when the argument is collected. So I'd expect that code to run the cleaner almost immediately.
j
Ahh yes, you’re right. This is what happens. I had a misunderstanding of how the Cleaner works. Thank you!
l
Yeah, it's reliable, but you have to use it right. :-)