Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Swift language leaks memory when having constant on constraints. #225

Closed
2 tasks done
mortyccp opened this issue Apr 19, 2016 · 26 comments
Closed
2 tasks done

Swift language leaks memory when having constant on constraints. #225

mortyccp opened this issue Apr 19, 2016 · 26 comments

Comments

@mortyccp
Copy link

mortyccp commented Apr 19, 2016

New Issue Checklist

Issue Info

Info Value
Platform ios
Platform Version 9.0
SnapKit Version 2.0
Integration Method cocoapods

Issue Description

class PrototypeViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()


        let v = UIView()
        view.addSubview(v)
        v.snp_makeConstraints { (make) in
            make.center.equalTo(view).inset(12)
        }
    }

}

The above lines of code will cause memory leak. You can examine the leak by using instrument leak tool.

@robertjpayne
Copy link
Member

@soapsign thanks for the report, I'll have a look later tonight.

@cherishloveyou
Copy link

have the same problem, run instrument leak

@googlb
Copy link

googlb commented Apr 28, 2016

Memory leak. Me too

@robertjpayne
Copy link
Member

@googlb @cherishloveyou @soapsign can any of you post the instruments trace showing the leak? I see a leak but it's not from SnapKit, rather it appears to be from Swift itself.

@robertjpayne robertjpayne removed the bug label Apr 30, 2016
@dominik-hadl
Copy link
Contributor

dominik-hadl commented May 3, 2016

@robertjpayne I am having the same issue, here's what I could get from Instruments so far.

In the first awakeFromNib function, there's just the classic snp_makeConstraints() call with some setup similar to the code above. I tried using [weak self] inside the closure in case it may be in some weird way related, but it looks like it's only related to the UIEdgeInsets (or EdgeInsets).

screen shot 2016-05-03 at 16 16 13

@robertjpayne
Copy link
Member

@NickSkull do you have the full instrument screenshot on that? It doesn't reveal much about what is leaking vs what's an allocation/call stack.

Also does it happen in viewDidLoad apposed to awakeFromNib? I've only tested the viewDidLoad as this is what the issue request was opened with.

@dominik-hadl
Copy link
Contributor

dominik-hadl commented May 4, 2016

@robertjpayne What exactly should I take a screenshot of? AFAIK There wasn't really anything relevant in allocations. When looking into code, Instruments show all these if let and else if let as leaking in this code - https://github.com/SnapKit/SnapKit/blob/develop/Source/Constraint.swift#L388 .

Haven't tried in viewDidLoad yet, but it does happen in viewWillAppear.

@robertjpayne
Copy link
Member

@NickSkull it looks like you've screenshotted the Details > Call Tree viewer. It'd be useful to also see what the Details > Leaks > Leaks By Backtrace look like.

As far as I can tell from your screenshot the leaks are occurring but not because of SnapKit but rather lower level libraries. swift_slowAlloc is a bit notorious on my radar for leaking lots and has nothing to do with SnapKit in reality.

@robertjpayne
Copy link
Member

Digging a bit deeper it looks entirely related around snp_constantForValue but reviewing my code I'm not really doing anything here it's all value types in that method and from the rest of the backtrace sounds like the Swift runtime/compiler is allocing memory it isn't then cleaning up.

@dominik-hadl
Copy link
Contributor

@robertjpayne Oh, I forgot to mention that - I don't think it's (entirely) SnapKit's fault, rather a Swift issue, but there usually is a workaround that makes the leaks go away. :D

Screenshot attached, I didn't attach it before, because there's IMO no value/clue in it.

screen shot 2016-05-04 at 15 11 41

@mortyccp
Copy link
Author

mortyccp commented May 4, 2016

Just a guess. Will it be related to snp_constantForValue is taking Any? as its parameter?

@dominik-hadl
Copy link
Contributor

@soapsign I tried switching to Any in case optionals affected it, but that didn't help. And since it can be ints, floats, even structs like UIEdgeInsets there isn't really any other option than to use Any.

@robertjpayne
Copy link
Member

Yea I'm not really sure how far to dig on fixing this, it's probably something we're going to have to wait until Swift 3.0 or something.

@robertjpayne robertjpayne changed the title Memory leak when having constant on constraints. Swift language leaks memory when having constant on constraints. May 4, 2016
@robertjpayne
Copy link
Member

I've renamed the issue, I don't want people to get scared that SnapKit is a memory sieve but I also don't want to close this. I'm happy to merge any PR's that resolve this I just personally don't have enough time at the moment to try and work around Swift in this instance.

@dominik-hadl
Copy link
Contributor

@robertjpayne Thanks for the info. I will also have a look at SnapKit 0.30.0 (if it can be compiled and run) and see if the issue is occurring there.

@robertjpayne
Copy link
Member

At the moment I think 0.30.0 is close but not quite ready to replace 0.20.0, I need to find a spare weekend to finish it up 👍

@molezzz
Copy link

molezzz commented May 7, 2016

Memory leak. Me too. When call ".inset()"

image

image

@dominik-hadl
Copy link
Contributor

@robertjpayne Just verified that 0.30.0 fixes the leak as far as I can see. Tested in multiple places and no leaks occurred anymore.

@robertjpayne
Copy link
Member

@NickSkull interesting, I'll see what I'm doing differently in 0.30.0 to get the constant values and see if I can backport it.

Saw your comment about a checklist, honestly I need to evaluate the codebase again to confirm what's left!

@dominik-hadl
Copy link
Contributor

@robertjpayne I think it can have something to do with the Any? being passed as parameter as opposed to it being a instance variable in version 0.30.0 (haven't checked source of 0.30.0 that much though). Related code here.

@robertjpayne
Copy link
Member

I just pushed 0.30.0.beta1 to Cocoapods, it actually should be quite stable though do expect a bug here or there potentially and the API has changed a bit.

@mortyccp
Copy link
Author

Recently, come across similar type of leak again on my project. And I found that its pretty much related to a Swift Bug related to casting protocol argument to concrete type in function. So I guess the cause of those leaks will be these casting

@robertjpayne
Copy link
Member

Does anyone know if this is resolved in Swift 2.3? I know it's fixed in Swift 3.0…

@robertjpayne
Copy link
Member

Closing this as it's invalid now I believe, with the advent of Swift 2.3/3.0 we should see this pretty much fade away in due time.

@Tbwas
Copy link

Tbwas commented Nov 9, 2016

I am having the same issue at Swift 3.0
image

@Adrift001
Copy link

I am also having the same issue at Swift3.1.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

8 participants