apple / swift-corelibs-foundation

The Foundation Project, providing core utilities, internationalization, and OS independence
swift.org
Apache License 2.0
5.27k stars 1.13k forks source link

[SR-5472] Swift 4.0 Memory leak on Linuxies using URLSession? #3831

Closed johnno1962 closed 6 years ago

johnno1962 commented 7 years ago
Previous ID SR-5472
Radar None
Original Reporter @johnno1962
Type Bug
Status Closed
Resolution Done
Environment Linux 16.04, Swift built from master 2017-07-16
Additional Detail from JIRA | | | |------------------|-----------------| |Votes | 0 | |Component/s | Foundation | |Labels | Bug, 4.0Regression, Linux | |Assignee | None | |Priority | Medium | md5: e055efa0a71c9a5f3c321efec7fe7e4e

Issue Description:

Hi, I’ve been looking at the Linux variant or Swift and found what could be a memory leak when using URLSession. If I place the code below in a file and execute using the REPL, the recorded memory continually increases on Linux by about roughly the amount of the Data received from the website. Memory also increases indefinitely on macOS but the effect is not quite so pronounced. This seems to be a regression relative to Swift 3.1.

import Foundation
import Dispatch

let url = URL( string: "http://www.bbc.co.uk/news" )!
let session = URLSession(configuration: .default)
let request = URLRequest(url: url)
var memory = rusage()

DispatchQueue.global().async {
    while true {
    sleep(1)
    session.dataTask(with: request) {
                   (data, response, error) in
        // NSLog( "Fetch \(data?.count ?? -1) \(String(describing: response)) \(String(describing: error))")
        if data == nil {
            return
        }
        getrusage(0, &memory)
        print( "Done \(memory.ru_maxrss)" )
    } .resume()
    }
}

RunLoop.main.run()
johnno1962 commented 7 years ago

This appears to be a recent regression (or is due to being a dev build?):

johnno@Ubuntu16:\~/swift-android-samples/swifthello$ \~/swift-4.0-DEVELOPMENT-SNAPSHOT-2017-07-13-a-ubuntu16.04/usr/bin/swift -O hello.swift
Done 150072
Done 150340
Done 150604
Done 150868
Done 151132
Done 151916
Done 152176
Done 152440
Done 152704
^C
johnno@Ubuntu16:\~/swift-android-samples/swifthello$ \~/swift-3.1.1-RELEASE-ubuntu16.04/usr/bin/swift -O hello.swift
Done 103084
Done 103600
Done 103880
Done 103880
Done 103880
Done 103880
Done 103880
Done 104144
Done 104144
Done 104144
Done 104144

johnno1962 commented 7 years ago

Seems to be a regression looking back at the 3.1 development snapshot (KB not increasing):

johnno@Ubuntu16:\~/swift-android-samples/swifthello$ \~/swift-3.1-DEVELOPMENT-SNAPSHOT-2017-06-14-a-ubuntu16.04/usr/bin/swift -O hello.swift
Done 133316
Done 134108
Done 134112
Done 134112
Done 134376
Done 134376
Done 134376
Done 134376
Done 134376
Done 134376
Done 134376
Done 134904
Done 134904
Done 134904
^C

johnno1962 commented 7 years ago

Graphing memory use, even Swift 3.1 showed continually increasing memory use though increasing at a slower rate.

belkadan commented 7 years ago

@phausler, an autorelease pool thing, maybe?

phausler commented 7 years ago

My guess is the differential of leaks is more pronounced because the swift implementation of NSURLSession and other Foundation classes are not nearly as optimized as the objective-c versions. That being said; if they are both leaking then we have achieved parity. It would be useful to build this example on Darwin based of swift-corelibs-foundation and run it in instruments. (you can attach Instruments to the TestFoundation target and run this code before the test main).

johnno1962 commented 7 years ago

It was the much greater leakage with Swift4 toolchains (on Linux) I was trying to point out (see the first comment.)

johnno1962 commented 7 years ago

PR raised which seems to fix this problem on Linux as well as Android https://github.com/apple/swift-corelibs-foundation/pull/1195