2017-02-16 6 views
0

コード解放しない:ループの中でNSKeyedArchiver archivedDataWithRootObject:メモリuseageこのような

NSMutableData *data = [NSMutableData dataWithLength:10*1024*1024]; 
for (int i = 0; i < 10; i++) { 
    NSData* archiveData = [NSKeyedArchiver archivedDataWithRootObject:data]; 
    NSLog(@"%lu", (unsigned long)[archiveData length]); 
} 

設定されたブレークポイントを、それがメモリuseageが増加します表示されるように:10メガバイト - > 20メガバイト....-> 100MB、forループから外れてもメモリは解放されません。

処理を続行すると(次のメインループに入る可能性があります)、メモリ使用量は100MB減少します。

PS:ARCをオンにする/ ARCをオフにし、キーワードリリースを使用することは同じ結果です。

答えて

2

ここで見ることができるのはNSAutoreleasePoolです。ループを次のように変更してください:

for (int i = 0; i < 10; i++) { 
    @autoreleasepool { // new autorelase pool 
     NSData* archiveData = [NSKeyedArchiver archivedDataWithRootObject:data]; 
     NSLog(@"%lu", (unsigned long)[archiveData length]); 
    } // drain autorelease pool 
} 

これにより、実行時間が短縮されますが、メモリの影響が大幅に軽減されます。

すべての便利なコンストラクタ([MyClass myClassWithSomething]に似た名前)は、自動解放プールに常駐するオブジェクトを常に返します(手動保持/解放コードの契約のため)。

デフォルトの自動解放プールは通常、現在のNSRunLoopに存在し、イベント処理サイクルごとに解放されます。 1つのサイクルであまりに多くのオブジェクトを作成すると、プールは成長し、成長します。したがって、内側の自動解放プールを手動で作成すると、より頻繁に排水されます。

+0

私は '' @ autoreleasepool'''を追加しようとしましたが、すぐにメモリを解放しません。私の問題はforループのメモリ使用量が大きすぎます。forループを '' 'dispatch_async '' '、それは動作しますが、私はこの解決策が嫌いです。 – waitianlou

+0

これはあなたのループで何をするかによって異なります。あなたが与えた例は、 'archivedDataWithRootObject'が要求したメモリを直ちに解放しなければならないので、もっとコードを知らなくてももっと教えてもらえません。 –

+0

あなたは大丈夫ですが、問題はUIPastebordのメモリが解放されていないことです。別の質問を投稿します、ありがとうございます。 – waitianlou

関連する問題