If I create instance of Kotlin Class in Swift Code...
# multiplatform
d
If I create instance of Kotlin Class in Swift Code and have strong reference to it, I can see this instance in memory graph. I expected if I set null to reference, instance will be disposed. Unfortunately I see this instance in memory. Why GC doesn’t clear memory?
k
1.3.40?
d
yes
k
The runtime caches a few allocations to cut down on alloc calls. May be that? https://github.com/JetBrains/kotlin-native/blob/master/runtime/src/main/cpp/Memory.cpp#L1171
If you're creating a single object, that will be tough to avoid. Maybe try creating a bunch and see if.the runtime is "leaking" them (i doubt it)
d
I dont understand. Do you want to say that is correct case for one object?
k
Yeah, I would expect a single object not to have it's memory cleared, but usually I confirm things before saying them. However, currently on a boat
So, it might be that
d
Copy code
Kotlin/Native provides an automated memory management scheme, similar to what Java or Swift provides. The current implementation includes an automated reference counter with a cycle collector to collect cyclical garbage.
I thought that
Copy code
reference counter
must clear memory
k
In 1.3.31 and earlier it would clear immediately. 1.3.40 has some optimizations. One of which is to queue deallocations and reuse allocations if appropriate
d
I’ve tried to create several instances and after each creation I delete reference. All objects are in memory
k
How many is several?
d
15
k
Threshold is 32 as I recall. Try 100, 1000, etc
d
100, 1000 - all in memory
k
Are you checking at a breakpoint?
Assume you're creating with a loop. Make sure you have an autorelease pool in Swift and check outside of it
d
I use Debug Memory Graph in Xcode
k
Post code
d
I tried with autorelease pool. It is same
k
Well, again, post code, but if you think you found a legit bug where Kotlin native is leaking memory in simple allocations that would be interesting news. Im on a phone and can't see your code so it's difficult to comment further
d
Copy code
var kotlinClass = KotlinClass()
        
        for _ in 1...1000 {
            autoreleasepool {
                kotlinClass = KotlinClass()
            }
        }
Copy code
class KotlinClass {
    fun foo() {
    }
}
k
Why are you assigning the variable outside of the Auto release pool?
Put the autorelease around the loop
d
Copy code
autoreleasepool {
            var kotlinClass = KotlinClass()
            for _ in 1...1000 {
                kotlinClass = KotlinClass()
            }
            print(kotlinClass)
        }
same
k
That leaks 1000 kotlin instances? Ok, well, I'd suggest creating a small sample project and posting to GitHub.
Can you screenshot the whole tool window?
d
k
With the memory debugger. Ideally a video of it. I want to verify what you're doing and I can try later. I'd be surprised if kotlin is leaking simple objects with no references to them, but I want to verify what you're doing to replicate. Presumably the memory debugger is stopping on some line. If you're measuring after 'viewDidLoad' that would be very interesting
d
I hope it is enough. On 1.3.30 Everything is fine - no memory leak
k
There also appears to be a min size trigger on GC, but I haven't tested much with that. I will say I've done large alloc tests and don't have macro size leaks
My guess is those objects are queued to be removed, but again, on a koat
*boat
Can't run anything directly
d
Thank for discuss) Strange for me that it was introduced so conceptual change. I know that for Java world it is ok, but not for Swift.
Copy code
Kotlin/Native provides an automated memory management scheme, similar to what Java or Swift provides.
k
New for me too. I'm used to the kotlin native model from earlier versions. However, they've improved performance significantly (or so I'm told ;)
o
@Dmitry Motyl please report an issue with reproducer. Could be problem in either K/N, Swift or your memory debugger.
s
autoreleasepool
shouldn’t be required in this particular case. This behaviour is likely caused by deferred reference counting implemented in 1.3.40. Add
kotlin.native.internal.GC.collect()
call to process the objects to be released.
o
@kpgalligan BTW, threshold of GC is 16384 at the moment, 32 is finalization queue threshold
s
Also note that manual
GC.collect
is not required for your application to work properly, because K/N memory manager invokes it automatically after the threshold has been reached.