2009-07-11 11 views
2

私は多少ココア初心者ですが、なぜこのコードでInstrumentsのリークグラフにスパイクが表示されているのか分かりません。それは小さな漏れ(すなわち、16バイト、漏れたオブジェクトは "Generalblock-16"です;それは唯一の漏洩オブジェクトであり、Self 100%と言われています)、1つのファイルを選択するかどうかにかかわらず、 12,000ファイル。私は、InstrumentsのExtended Detailビューに表示されているStack Traceの各行をダブルクリックしていますが、私のコード内のどの行にもつながっていません。メモリリークがどこから来るのか分からない

ご協力いただきありがとうございます。

Y.V.

P .:私のコードには何も問題はありません。疑いがありますが、漏れはバグか、私のコードと無関係なものです。このコードをそのまま使用するのは安全ですか?私のアプリに不安定さをもたらしたり、クラッシュなどを起こすのだろうか?

@implementation AppController 

-(IBAction)openTheOpenPanel:(id)sender 
{ 
    NSOpenPanel *openThePanel = [NSOpenPanel openPanel]; 
    [openThePanel setAllowsMultipleSelection:YES]; 

    if([openThePanel runModal] == NSOKButton) 
    { 
     NSArray *allTheFiles = [openThePanel filenames];  

     int theNumberOfFiles = [allTheFiles count]; 

     int i; 

     NSMutableDictionary * theDict; 
     theDict = [[NSMutableDictionary alloc] init]; 

     for (i=0; i < theNumberOfFiles; i++) { 
      NSString *thisFile = [allTheFiles objectAtIndex:i]; 
      NSString *theFileNum = [NSString stringWithFormat:@"%i", i]; 

      [theDict setObject:thisFile forKey:theFileNum]; 
     } 

     [theDict writeToFile:@"/tmp/test_file.txt" atomically:YES]; 

     [theDict release]; 
    } 
} 

@end 
+0

まず、配列ではなく数字列キーの辞書を使用するのはなぜですか?第2に、 'runModal'は悪いです - 代わりに非同期バージョンの1つを使います。それらはあなたのアプリの残りの部分をブロックすることはなく、それらのいくつかは別のウィンドウのシートとしてパネルを動かすことができます。 –

答えて

4

はあなたのコード

http://clang-analyzer.llvm.org/

そして、それが指摘する一つ一つを解決する上で打ち鳴らす静的アナライザを実行してみてください。私はそれが間違っていたことを指摘したことは一度もありません。漏れやその他の参照関連の問題を発見することは特に優れています。

1

コードはよく見えます!あなたが示したことにメモリリークはありません。あなたがしたい場合は、次のようにtheDict宣言することができます。

theDict = [[[NSMutableDictionary alloc] init] autorelease]; 

を「自動解放」を呼び出す自動解放プールにオブジェクトを追加し、あなたの関数が実行された後、それが自動的に解除されます。それは便利です - あなたがリリースを呼び出すことを覚える必要はないからです。いずれにせよ、ここではうまくいくでしょう。

この機能を呼び出すたびにアプリがリークするのはなぜですか?インストゥルメントがリークが発生したコード行を表示していない場合は、システム内に何かが存在する可能性があります。私の経験では、ランダムなシステムの問題から頻繁にいくつかの小さなリークが発生します。

EDIT:

このサイズの漏れがあなたのアプリで任意の不安定性が発生することはありません。 メモリの大きな塊を含む

  1. リーク(NSDataのかNSImageでは、オブジェクト、など...)ループ内の
  2. リーク、または機能に:あなたはメモリリークを探しているときは、のために気をつけたいです が繰り返し呼び出されます(これにより、重要度は になります)。

でも、あなたのアプリが約28MBのRAMを取得する場合でも、16バイトまたは32バイトのリークは多少ありません。インスツルメントは、通常、アプリが起動したときにわずかなリークが報告されます。大きな問題ではありません。深刻なユーザーは、使用可能なすべてのメモリが漏れなくなるまでアプリを実行し続けることができるため、アプリが実行されるにつれてより多くのメモリをリークさせないようにしたいだけです。あなたのアプリがまだそれを使用していると思うので、OSはリークされたメモリを再利用しないので、最終的に新しいオブジェクトにメモリを割り当てることができなくなります。

希望に役立ちます!あなたはそれを初期化/ ALLOCまでのメモリアドレス - と未知の - それは何も解決しますが、私はいつもそうしないとtheDict WILは、おそらくいくつかの奇妙なを持っている

NSMutableDictionary * theDict = nil; 

NSMutableDictionary * theDict; 

を変更することをお勧めすることを

1

ありません。あなたがこれを行う場合:

NSMutableDictionary * theDict; 
if (theDict) { 
    // condition is true 
} 

条件が満たされます、あなたはtheDictを自分で初期化されていなくても。

0

こんにちは!あなたの迅速な答えに感謝します!

ベン、ご意見ありがとうございます。あなたが提案したように辞書を自動リリースするのは、コードへの私の最初のアプローチでしたが、リークしたので、コードを自動リースから手作業の割り当てと解放に変更しました。残念ながら、同じオブジェクトとリーク量がリークします。

リークの原因となっているのが私のコードではない場合、あなたが言及したように、システムに何かがあるだけですが、わずかなリークがあってもコードを使用するのは安全でしょうか?それとも私のアプリで不安定やクラッシュを引き起こすでしょうか?

私はこれまでの方法で広範なテストを行ってきましたが、これまでのところ私のテストでは何の問題も見せていませんでした(私は機器を使ってリークがあることに気がつきました)。

もう一度お手数をおかけします。そのコードで

0

、あなたは漏れの原因であり得る四つの可能なラインがあります。

  1. NSOpenPanel *openThePanel = [NSOpenPanel openPanel];
  2. [openThePanel setAllowsMultipleSelection:YES];
  3. if([openThePanel runModal] == NSOKButton)
  4. NSArray *allTheFiles = [openThePanel filenames];

をそれぞれをコメントアウトしてみ1つ - あなたがouにコメントするときにデータをあざ笑うopenPanelの呼び出しやファイル名の問い合わせを行い、if文に対してrunModalが偽装されていることを確認します。

は、リークディテクタの王、

0

valgrind ...そしてあなたが担当するライン見ることができますし、戻ってそれに従って、漏れがないため、時間とテストに1つを、それらをコメントアウトported to OS Xてきました。 valgrindは、メモリリークを検出し、アロケーションサイトがどこにあったかを正確に伝え、オブジェクトが割り当てられたときにコールスタック上にあったものをさらに重要にします。 valgrindは、ライフセーファーです!

1

1)実行可能な環境変数にNSZombieEnabledがYESに設定されていないことを確認してください。代わりに、呼び出し元の

2):

theDict = [[[NSMutableDictionary alloc] init] autorelease]; 

あなたは、単に呼び出すことができる必要があります:

theDict = [NSMutableDictionary dictionary]; 

彼らは基本的に同じものです。

関連する問題