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

[SR-14194] URLSession shared - memory leak #4226

Closed
swift-ci opened this issue Feb 12, 2021 · 5 comments
Closed

[SR-14194] URLSession shared - memory leak #4226

swift-ci opened this issue Feb 12, 2021 · 5 comments

Comments

@swift-ci
Copy link
Contributor

Previous ID SR-14194
Radar rdar://problem/74274732
Original Reporter telcy (JIRA User)
Type Bug
Status Resolved
Resolution Invalid
Additional Detail from JIRA
Votes 0
Component/s Foundation
Labels Bug
Assignee None
Priority Medium

md5: 39fc7d661ef45654ab81ab331c820df6

Issue Description:

I have a scheduled timer requesting a url every x seconds. For some reason URLSession.shared fills the memory slowly over time and never frees it.

import Foundation
DispatchQueue.global(qos: .default).async {
    let url = URL(string: "https://upload.wikimedia.org/wikipedia/commons/thumb/c/c2/Italian_States-Piacenza_1626_2_Doppie.jpg/2880px-Italian_States-Piacenza_1626_2_Doppie.jpg")!
    Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { timer in
        URLSession.shared.dataTask(with: url) { _, _, _ in
            
        }.resume()
    }
    RunLoop.current.run()
}
RunLoop.main.run()
@typesanitizer
Copy link

@swift-ci create

@swift-ci
Copy link
Contributor Author

Comment by Jascha Burmeister (JIRA)

Another example. Memory is growing over time and only gets freed after completing the loop.

import Foundation


let url = URL(string: "https://upload.wikimedia.org/wikipedia/commons/thumb/c/c2/Italian_States-Piacenza_1626_2_Doppie.jpg/2880px-Italian_States-Piacenza_1626_2_Doppie.jpg")!


for i in 1...200 {
    autoreleasepool {
        print(i)
        URLSession.shared.dataTask(with: url) { _, _, _ in


        }.resume()
        sleep(1)
    }
}

RunLoop.main.run()

@swift-ci
Copy link
Contributor Author

Comment by Jascha Burmeister (JIRA)

I decided to rewrite my application in Rust and surprisingly had the same memory issue. Same code runs fine on Linux. There seems to be a memory leak down the network request stack.

use reqwest;
use std::{thread::sleep, time::Duration};

fn main() {
    // memory grows around 0.1 MB every 10 seconds
    loop {
        let _ = reqwest::blocking::get("https://jsonplaceholder.typicode.com/posts");
        sleep(Duration::from_millis(10));
    }
}

@typesanitizer
Copy link

Here's the message I received:

The session needs to be invalidated.

You can check out: https://developer.apple.com/documentation/foundation/urlsession

Important

The session object keeps a strong reference to the delegate until your app exits or explicitly invalidates the session. If you don’t invalidate the session, your app leaks memory until the app terminates.

@typesanitizer
Copy link

From what I understand based on the discussion in this reddit thread, the above doesn't quite answer how to fix the leak, since there is no delegate in the example. https://www.reddit.com/r/swift/comments/ms5orj/possibly_memory_leak_in_macos_network_request/

However, since this issue is related to the networking stack and not the open source toolchain (Swift, LLDB, SourceKit etc.), and a separate Feedback has been filed (FB9076036), I'm going to leave this as Resolved instead of reopening it.

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
@shahmishal shahmishal transferred this issue from apple/swift May 5, 2022
This issue was closed.
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

2 participants