我想在附加的java对象清理后释放本机资源。
我想提供额外的变量进行清理,所以我继承了 PhantomReference。但该引用并未排队到 ReferenceQueue 中。
这是我使用 Kotlin/JVM 的最小示例
val queue = ReferenceQueue<Any>()
var obj: Any? = Any()
val phantomRef = PhantomReference(obj!!, queue) // this works!!
// val phantomRef = object: PhantomReference<Any>(obj!!, queue) {} // this does not works even there are no extra fields :(
println("Created PhantomReference")
obj = null // Clear strong reference
System.gc() // Trigger garbage collection
Thread.sleep(1000) // Wait for GC
val ref = queue.poll()
if (ref != null) {
println("PhantomReference enqueued!")
} else {
println("PhantomReference not enqueued.")
}
编辑 我又发现了一个奇怪的案例:
// this works
val phantomRef = PhantomReference(obj!!, queue)
// this does not works
PhantomReference(obj!!, queue)
我认为这可能与优化有关,但我不确定
这是由 PhantomReference 主导的,它本身也被 GC 了,但不幸的是,这并不能解决主要问题。
感谢@user85421指出这一点。
感谢@Slaw,我解决了我的问题。
val queue = ReferenceQueue<Any>()
val refs = mutableListOf<PhantomReference<Any>>()
repeat(100) {
var obj: Any? = Any()
refs.add(object: PhantomReference<Any>(obj!!, queue) {})
obj = null // Clear strong reference
System.gc() // Trigger garbage collection
Thread.sleep(10000) // Wait for GC
val ref = queue.poll()
if (ref != null) {
println("PhantomReference enqueued!")
} else {
println("PhantomReference not enqueued.")
}
}
这是我的新代码和参考,在每次第二次迭代时排队。(我不知道为什么它是每次第二次迭代,但至少它完成了它的工作)