Can `AtomicRef` (common version) leak memory like ...
# kotlin-native
l
Can
AtomicRef
(common version) leak memory like
AtomicReference
(native version)? And if so, how to avoid memory leak given that I write code in common?
n
Clear the reference to null when you no longer need the referenced object.
l
Got it. Btw can references be shared between threads without being frozen? Still talking about writing code in common.
p
As far as I have seen, in both AtomicRef and AtomicReference, the value stored inside references are themselves frozen. So yes, refs can be shared among threads without being frozen, but since the values are frozen, you can't mutate them. You will be able to update the value though.
l
Interesting. What I'm going to store in
AtomicRef
is an object that contains a
Long
(immutable) and an
AtomicInt
. There won't be issues regarding the
AtomicInt
right? (i.e. I can change it as normal)
p
I havent tried it yet, but I dnt think it will be a problem. Although I read about FreezableAtomicReferences being used in AtomicFu library for AtomicReferences
k
AtomicInt is fine. “refs can be shared among threads without being frozen” Technically not correct. The AtomicRef is frozen, but there’s magic under the hood to let you change the value. All versions of AtomicRef in native need to be nulled out to ensure GC. That may change, though.
l
Thank you all
p
"refs can be shared among threads without being frozen Technically not correct" . Can you please elaborate Kevin? Thanks
k
The AtomicReference class itself is frozen. By that I mean
ref.isFrozen
will return true. However, you can still change the value it holds. So, it’s “frozen” but “mutable”.
p
and what magic is that, that it is able to still modify?
Copy code
public class AtomicReference<T>(private var value_: T) {
    // A spinlock to fix potential ARC race.
    private var lock: Int = 0
Internally, each piece of data is just a C++ field. That’s
value_
and
lock
Copy code
void Kotlin_AtomicReference_set(KRef thiz, KRef newValue) {
    Kotlin_AtomicReference_checkIfFrozen(newValue);
    AtomicReferenceLayout* ref = asAtomicReference(thiz);
    SetHeapRefLocked(&ref->value_, newValue, &ref->lock_);
}
The value is changed in the C++ level, which bypasses the normal frozen mutability check.
p
Got that. I saw one of your talks in which you mentioned that the freeze happens at memory level. What did you mean by that? Does it mean that freeze happens at the level of Kotlin Runtime memory access? and since everything is a c++ pointer if you go to that level and we can just play around with those like normal c++ pointers
and the way it changed a frozen object, let's say I implement a similar functionality by going to C++ level, will I be able to change anything myself (assuming my impl is correct)?
You can do whatever you want in C++, but I would HIGHLY suggest avoiding it unless you are in extremely odd circumstances
I lost weeks of my life in 2017 trying to work around some of the concurrency rules in KN. All I accomplished was creating race conditions
😂 3
p
Understood. Thanks kevin for patiently answering the queries. You are really a great help in understanding the depth of KN.
👍 1