

`NSURLSession` を利用して 60個のファイル（それぞれ 2M程度）を連続ダウンロードしたいと思います。  
以下のようなサンプルコードを作成し、うまくダウンロードできました。

ボタンを押すと 60個のファイルをダウンロードします。ダウンロードが終了すると再びボタンが有効になり、押下すると再度ダウンロードが始まります。

しかしながら、メモリ関連の問題が発生しました。

iOS7 では繰り返しダウンロードしても占有メモリは 50M程度で一定なのですが、  
iOS8 ではダウンロード中に徐々に占有メモリが増加し、 1回実行すると
170MB程度となります。さらに繰り返し実行（Startボタンの押下）するとさらに占有量が増し、やがて Memory Warning
が発生し、ついにはクラッシュしてしまいます。

どなたか解決の糸口をご教授していただける方、何卒宜しくお願いします。

[code]

    #import "ViewController.h"
    
    #define URL_MODEL_STRING @"http://sample.com/sample_%03d.pdf"
    #define MAX_FILE_NUMBER 60
    
    @interface ViewController ()<NSURLSessionDownloadDelegate>{
        NSURLSessionConfiguration* _conf;
        NSURLSession*              _session;
        NSURLSessionDownloadTask*  _downloadTask;
    
        int _currentFileNumber;
    
       __weak IBOutlet UIButton *_startButton;
    }
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
    
        _conf = [NSURLSessionConfiguration defaultSessionConfiguration];
    }
    
    
    - (IBAction)startButtonPushed:(id)sender {
    
        _startButton.enabled = NO;
    
        _session = [NSURLSession sessionWithConfiguration:_conf
                                                 delegate:self
                                            delegateQueue:[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
    
[/code]


CC BY-SA 3.0
2015-01-14T05:13:45.613
4527
2015-01-14T07:49:53.017
2015-01-14T07:24:57.003
5519
7365
question
ios objective-c ios8 nsurlsession memory-leaks
NSURLSession による連続ダウンロードにおけるメモリリーク (iOS8)


私の環境でも再現しました。iOS 8.1.2, iPhone 6 Plus

ただし、Xcodeから実行してデバッガと接続してるという状況でのみ起こるようです。  
試しにInstrumentsで調べてみましたが、メモリの使用量は一定で、特に開放されてないということはありませんでした。（下記スクリーンショット）

![Instruments](https://i.stack.imgur.com/C6ykq.png)

私の環境ですとデバッグ中はだいたい３回めのダウンロードでメモリ不足でクラッシュしましたが、デバッガと繋がず、単に実機で実行するぶんには、何度ダウンロードしてもクラッシュすることはありませんでした。

同様の状況が起こっているひとは他にもいるようですが、同じくデバッガに接続してるときだけ起こるということです。  
<https://stackoverflow.com/questions/27280486/nsurlsession-download-task-
grows-memory-in-debug-with-default-session-config>

現象は謎ですが、実際の使用で起こらないのであれば、Appleにバグレポートしつつ、ひとまずは現状のまま使うということでもよいのではないでしょうか。


CC BY-SA 3.0
2015-01-14T07:49:53.017
4538
2015-01-14T07:49:53.017
2017-05-23T12:38:55.250
-1
5519
4527
answer