Runtime
Runtime copied to clipboard
Memory Leaks in property setters
I believe there is a memory leak with the below code:
https://github.com/wickwirew/Runtime/blob/5638402223ac41a4f3ddc45993534d8ff9c3f398/Sources/Runtime/Utilities/GettersSetters.swift#L41
I think what's happening is if the value is not initialised it will be fine and no leak will occur (construction) but if you're replacing an existing value the old value is nullified without being free'd since swift loses track of it.
Ok so here is an easy to reproduce example below. You will notice the START
inner value that is replaced never gets deallocated
import Runtime
class MySubObject {
let label: String
init(label: String) {
self.label = label
}
deinit {
print("MySubObject(label: \(self.label)) deinit")
}
}
class MyObject {
let inner: MySubObject
init(label: String) {
self.inner = MySubObject(label: label)
}
deinit {
print("MyObject(inner.label: \(self.inner.label)) deinit")
}
}
var obj: MyObject = MyObject(label: "START")
var newInner = MySubObject(label: "UPDATE")
let property = try Runtime.typeInfo(of: MyObject.self).property(named: "inner")
try property.set(value: newInner, on: &obj)
obj = MyObject(label: "FINALISE")
@wickwirew would be interested if you have any thoughts on this -- it's a really tricky thing and I'm not sure there is actually any feasible solution since we can't use Unmanaged<X>
or anything to try and munge the ref counting and sorts.
At first glance, we may just need to make a call to swift_release
manually for any heap values.
We ended up having to remove runtime entirely and use sourcery for our magic "reloading". Unfortunately didn't seem like there was a good fix that we felt was safe enough.
We just ran into this in our project. Are there any plans to fix this? We started using Runtime pretty heavily, so I'm a bit concerned that these leaks will add up. We're thinking about using Unmanaged
to work around this, but are a bit concerned that the fix will work against us if it's fixed in the library.