wasyl
02/05/2021, 7:39 AMinCoroutine {
var foo: Foo? = Foo()
val fooRef = WeakReference(foo)
triggerAndWaitForGc()
assert(fooRef.get() != null)
println(foo) // Test passes if this is removed
inCoroutine {
foo = null
triggerAndWaitForGc()
assert(fooRef.get() == null)
}
}
So first I hold Foo
in a strong reference (variable) and assert WeakRef
also has a reference to it. But later I set foo = null
, at which point I expect that there’s no strong reference to Foo
and it can be GC-ed. This doesn’t happen in the snippet above, because println(foo)
generates the following bit:
Foo var9 = (Foo)foo.element;
var5 = false;
System.out.println(var9);
and var9
is never cleared, so there will be a strong reference to Foo
as long as that coroutine is active (?). Is this expected?
Snippet with full code: https://pl.kotl.in/25D0_X5w8Tijl
02/05/2021, 7:54 AMwasyl
02/05/2021, 7:57 AMTijl
02/05/2021, 8:00 AM}
from you first block, you would still expect to see the value of “foo” there since it’s in scopewasyl
02/05/2021, 8:07 AMfoo
but in the same scope doesn’t have this issueTijl
02/05/2021, 8:10 AMwasyl
02/05/2021, 8:11 AMwhere do you see this reference?in IJ when I open Kotlin Bytecode window and hit Decompile
I guess you can easily write the same code in Java for comparisonAs it turns out, I can’t:
Tijl
02/05/2021, 8:18 AMprintln(foo)
before the end of the block, it correctly prints null
wasyl
02/05/2021, 8:34 AM