https://kotlinlang.org logo
#multiplatform
Title
# multiplatform
d

Dmitry Motyl

06/21/2019, 9:31 AM
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

kpgalligan

06/21/2019, 9:34 AM
1.3.40?
d

Dmitry Motyl

06/21/2019, 10:11 AM
yes
k

kpgalligan

06/21/2019, 10:17 AM
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

Dmitry Motyl

06/21/2019, 10:21 AM
I dont understand. Do you want to say that is correct case for one object?
k

kpgalligan

06/21/2019, 10:23 AM
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

Dmitry Motyl

06/21/2019, 10:26 AM
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

kpgalligan

06/21/2019, 10:28 AM
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

Dmitry Motyl

06/21/2019, 10:36 AM
I’ve tried to create several instances and after each creation I delete reference. All objects are in memory
k

kpgalligan

06/21/2019, 10:36 AM
How many is several?
d

Dmitry Motyl

06/21/2019, 10:37 AM
15
k

kpgalligan

06/21/2019, 10:37 AM
Threshold is 32 as I recall. Try 100, 1000, etc
d

Dmitry Motyl

06/21/2019, 10:40 AM
100, 1000 - all in memory
k

kpgalligan

06/21/2019, 10:48 AM
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

Dmitry Motyl

06/21/2019, 10:50 AM
I use Debug Memory Graph in Xcode
k

kpgalligan

06/21/2019, 10:51 AM
Post code
d

Dmitry Motyl

06/21/2019, 10:55 AM
I tried with autorelease pool. It is same
k

kpgalligan

06/21/2019, 10:58 AM
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

Dmitry Motyl

06/21/2019, 11:05 AM
Copy code
var kotlinClass = KotlinClass()
        
        for _ in 1...1000 {
            autoreleasepool {
                kotlinClass = KotlinClass()
            }
        }
Copy code
class KotlinClass {
    fun foo() {
    }
}
k

kpgalligan

06/21/2019, 11:06 AM
Why are you assigning the variable outside of the Auto release pool?
Put the autorelease around the loop
d

Dmitry Motyl

06/21/2019, 11:08 AM
Copy code
autoreleasepool {
            var kotlinClass = KotlinClass()
            for _ in 1...1000 {
                kotlinClass = KotlinClass()
            }
            print(kotlinClass)
        }
same
k

kpgalligan

06/21/2019, 11:12 AM
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

Dmitry Motyl

06/21/2019, 11:23 AM
k

kpgalligan

06/21/2019, 11:32 AM
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

Dmitry Motyl

06/21/2019, 11:53 AM
I hope it is enough. On 1.3.30 Everything is fine - no memory leak
k

kpgalligan

06/21/2019, 11:55 AM
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

Dmitry Motyl

06/21/2019, 12:00 PM
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

kpgalligan

06/21/2019, 12:02 PM
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

olonho

06/23/2019, 8:20 AM
@Dmitry Motyl please report an issue with reproducer. Could be problem in either K/N, Swift or your memory debugger.
s

svyatoslav.scherbina

06/23/2019, 8:53 AM
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

olonho

06/23/2019, 9:03 AM
@kpgalligan BTW, threshold of GC is 16384 at the moment, 32 is finalization queue threshold
s

svyatoslav.scherbina

06/23/2019, 9:16 AM
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.
6 Views