Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Memory leak in Swift structures - How to fix this?

I'm developing an application in Swift 2 (Xcode 7 beta 3) and I'm trying to use value types (structs and enums) where possible. According to Apple's documentation about memory management, working with value types should not cause any retain cycles and it should just work.

But today I encountered a huge amount of memory leaks in event handling code. I tracked it down and reduced the problem to the following minimal example.

Let's say there is a protocol Item which defines a single property value:

protocol Item {

    var value: String { get }

}

We then create a concrete struct which implements the Item protocol and adds an additional property additionalValue. Let's call the struct FooItem.

struct FooItem<T>: Item {

    let value: String
    let additionalValue: T

    init(value: String, additionalValue: T) {
        self.value = value
        self.additionalValue = additionalValue
    }

}

The third piece of the puzzle is another struct which wraps an item implementing the Item protocol. It's called ItemWrapper.

struct ItemWrapper {

    let item: Item

    init(item: Item) {
        self.item = item
    }

}

If profiled in Instruments using the Memory Leaks configuration, a memory leak appears every time an ItemWrapper value is created with a FooItem.

let item = FooItem(value: "protocol value", additionalValue: "foo item value")  
let _ = ItemWrapper(item: item) 

Instruments screenshot 1Instruments screenshot 2

Here is the example Xcode project and the Instruments file: https://www.dropbox.com/s/z6ugxzxqggrv1xl/SwiftStructsMemoryLeak.zip?dl=0

The whole code example can be viewed in this Gist: https://gist.github.com/lukaskubanek/4e3f7657864103d79e3a

Here is the bug report: rdar://21375421

Is it a bug in the Swift compiler or am I doing anything wrong?


EDIT 1: As suggested in the comments, I reposted this question on the Apple Dev Forum in order to draw more attention from the Swift community and potentially from the developers of the language. Due to a migration of the dev forums during WWDC 2015 I had to post an updated question on the new forums. Here is the link: https://forums.developer.apple.com/message/9643


EDIT 2: The problem I originally posted in the example code seems to be resolved in Swift 2.0. Since it didn't solve the issues in my app I made another modification to the example code. Now the FooItem's additional property has a generic type and FooItem is annotated with the type and thus a generic type. This is how I'm using it in my app and it still causes a memory leak, but this time when the ItemWrapper is initialized rather than when accessing the property.


EDIT 3: Fully updated the question to the modified problem which persists in Swift 2.0 and uploaded new example Xcode project.

like image 996
Lukas Kubanek Avatar asked Jun 03 '15 19:06

Lukas Kubanek


People also ask

What causes memory leaks in Swift?

A memory leak occurs when allocated memory becomes unreachable and the app can't deallocate it. Allowing an allocated-memory pointer to go out of scope without freeing the memory can cause a memory leak. A retain cycle in your app's object graph can also cause a memory leak.


1 Answers

Although I haven't got a response from Apple neither on the dev forums nor in the bug tracker and I haven't found anything related to this issue in the release notes of the latest beta versions, it seems to be solved in the Swift compiler in Xcode 7 beta 5. (Maybe it also works in beta 4. The last version I've checked was beta 3.)

The demo project doesn't produce the memory leak anymore. The same is true for my app. Yay!

enter image description here

like image 72
Lukas Kubanek Avatar answered Sep 20 '22 05:09

Lukas Kubanek