Memory Leak in Continuous Downloads with NSURLSession (iOS8)

Asked 2 years ago, Updated 2 years ago, 101 views

I would like to download 60 files (about 2M each) continuously using NSURLSession.
I created the following sample code and successfully downloaded it.

Press the button to download 60 files.When the download is finished, the button is activated again, and when pressed, the download begins again.

However, a memory-related problem occurred.

iOS 7 has a constant memory footprint of about 50M even after repeated downloads, but
 iOS 8 gradually increases the amount of memory it occupies during the download, and once it runs, it will be around 170MB.If you run it repeatedly (press the Start button), it will take up more space, eventually triggering Memory Warning and eventually crash.

I would appreciate it if you could give me a clue to the solution.

#import "ViewController.h"

#define URL_MODEL_STRING@"http://sample.com/sample_%03d.pdf"
#define MAX_FILE_NUMBER60

@ interface ViewController()<NSURLSessionDownloadDelegate>{
    NSURLSessionConfiguration*_conf;
    NSURLSession*_session;
    NSURLSessionDownloadTask*_downloadTask;

    int_currentFileNumber;

   __weak IBOutlet UIButton*_startButton;
}

@end

@implementation ViewController

- (void) viewDidLoad{
    superviewDidLoad;

    _conf = NSURLSessionConfiguration defaultSessionConfiguration;
}


- (IBAction) startButtonPushed: (id) sender {

    _startButton.enabled = NO;

    _session = [NSURLSession sessionWithConfiguration:_conf]
                                             delete —self
                                        deleteQueue: [NSOperationQueue mainQueue];
    _currentFileNumber=1;

    [self downloadFileWithNumber:_currentFileNumber];
}


- (void) downloadFileWithNumber: (int) fileNumber {
    NSURL*url = [self urlWithFileNumber: fileNumber];
    _downloadTask=[_session downloadTaskWithURL:url];

    [_downloadTask resume];
}


- (NSURL*) urlWithFileNumber: (int) fileNumber {
    return [NSURL URLWithString: [NSString stringWithFormat: URL_MODEL_STRING, fileNumber]];
}


# pragma mark - NSURLSessionDownloadDelegate

- (void) URLSession: (NSURLSession*) session
      downloadTask: (NSURLSessionDownloadTask*) downloadTask
 didFinishDownloadingToURL:(NSURL*) location{

    NSLog(@"fileNumber:%d location:%@",_currentFileNumber, location);

    // TODO: Move downloaded temporary file to another place.


    if(_currentFileNumber==MAX_FILE_NUMBER){
        NSLog(@"Download complete.");
        [_session invalidateAndCancel];
        _startButton.enabled = YES;
        return;
    }

    _currentFileNumber++;

    [self downloadFileWithNumber:_currentFileNumber];
}

- (void) DidReceiveMemoryWarning {
    super didReceiveMemoryWarning;

    NSLog (@"didReceiveMemoryWarning");
}

@end

ios objective-c ios8 nsurlsession memory-leaks

2022-09-30 20:32

1 Answers

I reproduced it in my environment.iOS 8.1.2, iPhone 6 Plus

However, it seems to occur only when running from Xcode and connecting to the debugger.
I tried using Instruments and found that the memory usage was constant and not particularly open.(Screenshot below)

Instruments

In my environment, during debugging, it crashed due to lack of memory in the third download, but it didn't connect with the debugger and it didn't crash no matter how many times I downloaded it.

It seems that there are other people who are experiencing similar situations, but it only happens when they are also connected to the debugger.
https://stackoverflow.com/questions/27280486/nsurlsession-download-task-grows-memory-in-debug-with-default-session-config

The phenomenon is a mystery, but if it doesn't happen in actual use, I think it's okay to report a bug to Apple and use it as it is.


2022-09-30 20:32

If you have any answers or tips


© 2024 OneMinuteCode. All rights reserved.