2012-04-18 10 views
0

単純なアルゴリズムを持つretain/releaseプロジェクトがあります。私は100000個のオブジェクトの変更可能な配列で始まり、5秒間隔ごとに1000個のオブジェクトを最初から削除し、最後に1000個のオブジェクトを追加します。理論的には、私のメモリフットプリントは、遅れても同じままでなければなりませんが、それはある程度上がるまで一貫して上昇します。しかし、 "[array removeAllObjects]"ですべてのオブジェクトを削除して配列を解放しても、一部のメモリだけが戻ってくるわけではありません。私はデバッガなしでリリーススキームで動作しており、アクティビティモニタを使用してメモリ使用量を追跡しています。あなたはあなたが自動解放オブジェクトを作成しているオブジェクトが配列から削除されるとメモリが再生されない

NSURL *url = [NSURL URLWithString:@"http://www.apple.com"]; 

使用してNSURLを作成

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification{ 
    array = [[NSMutableArray alloc] init]; 
    for(int i = 0; i<100000; i++){ 
     NSURL *url = [NSURL URLWithString:@"http://www.apple.com"]; 
     [array addObject:url]; 
    } 
    self.t = [NSTimer scheduledTimerWithTimeInterval:10 target:self selector:@selector(addAndRemove:) userInfo:nil repeats:YES]; 

}

-(IBAction)addAndRemove:(id)sender{ 
    [array removeObjectsInRange:NSMakeRange(0, 1000)]; 

    for(int i = 0; i<1000; i++){ 
     NSURL *url = [NSURL URLWithString:@"http://www.apple.com"]; 
     [array addObject:url]; 
    } 
} 

-(IBAction)clear:(id)sender { 
    [array removeAllObjects];  
    [array release]; 
    [t invalidate]; 
    t = nil; 
} 

答えて

3

アクティビティモニタでメモリ使用量を監視することは、かなり信頼性がありません。まず、どのメモリフィールド(仮想プライベートメモリ、リアルプライベートメモリ、リアル共有メモリ、またはリアルメモリ)を見ていますか?

第2に、コードが割り振り要求を行うとき、通常は直接または間接的にmallocルーチンに渡されます。 mallocルーチンは、すでに持っているメモリからの要求を満足させようとします。それができない場合は、システムからさらに要求します。メモリを解放すると、mallocに戻ります。 Mallocは必ずしもそれをシステムに返すわけではありません。それは将来の要求をより迅速に満たすためにそれを保つかもしれない。したがって、あなたのプログラムが割り当てられたすべてのものを解放していても、少なくともあなたのプロセスのメモリ使用量は、少なくとも完全には下がらないかもしれません。

プログラムがメモリを正しく管理しているかどうかを確認する適切な方法は、漏電と割り当てのツールでInstrumentsを使用することです。

+2

私は強い声明を述べるだろう。 AMによるメモリ使用量の監視は、暴走の激しさを克服するために大して役に立たない。 – bbum

+0

私は実際のメモリサイズを見ています。私はすでにリーク機器を使用しており、メモリリークはありません。アロケーションツールを使用しているとき、私は何を探すべきですか? – dpham

+0

私は割り当て装置でテストを行い、正しく動作しました。あなたが言ったように、アクティビティモニターは非常に不正確です。 – dpham

3

。自動解放されたオブジェクトは自動解放プールに格納され、プールが空になると破棄されます。メインプールが起動すると、毎秒60秒ごとにメインプールがフラッシュされるため、オブジェクトが期待どおりにリリースされないことがあります。

forループを@autoreleasepool {}ブロックでラップして、ループ内で作成された自動解放オブジェクトが即座にフラッシュされるようにするか、alloc/initを使用してNSURLを作成します。

NSURL *url = [[NSURL alloc] initWithString:@"http://www.apple.com"]; 

次に、メモリ使用量が変化するかどうかを確認します。

+0

メインプールは「60分おきにフラッシュされません」。アプリケーション・オブジェクトはそのプールを廃棄し、アプリケーションがイベントを処理するたびに新しいプールに置き換えます。 (また、これは長時間実行されるバックグラウンドアプリケーションを噛んでしまう可能性があります。)さらに、コードのランダムな行に目を奪うのではなく、Instrumentsを使用してメモリの最適化を通知する方が良いでしょう。 –

+0

私はこれをメモリ最適化戦略として提案していませんでしたが、アレイが破棄されたときにメモリが解放されなかった理由の説明として考えました。私はケンの答えがもっとそうであると認めます。 –

関連する問題