4

シミュレーターで問題なく動作する iPhone アプリがあります。絶対に必要ではないものをすべて取り除くことで、メモリの警告にうまく対応します。デバイスで実行すると、うまく動作します。しかし、一定量使用すると、エラー コード 101 でクラッシュします。これは、メモリ使用量が原因で OS が強制終了したことを示しています。メモリの警告が表示され (ログに記録しています)、アプリはそれに応答しますが、その後すぐに停止します。

Instruments で (デバイスまたは sim のいずれかで) アプリを見ると、リークは見つかりません。さらに、正味のメモリ使用量は 600 ~ 700k バイトの範囲です。アプリのさまざまなビューから移行すると、(予想どおり) メモリ使用量が増加しますが、ビューとコントローラが解放されて解放されると、メモリ使用量が以前ほど低くなることはありません。ただし、追加は通常、1000 ~ 2000 バイトの範囲内のものにすぎません。したがって、Leaks はリークを示していませんが、どこかに問題があると思われます。また、割り当てているすべてのオブジェクトを確認しましたが、すべてが期待どおりに再利用されているようです。増加し続けている唯一のオブジェクトは GeneralBlock-N (N は数値) です。

Instruments のネット使用量の数値に注意を払う必要はありませんか? 問題を診断するための次のステップは何ですか?

追加: 私は malloc() や、私が担当するバッファを返す CoreFoundation ライブラリへの呼び出しを行っていません。私が行っている Obj-C 以外の呼び出しは、ステートメントを NSLog に記録することだけです。

4

5 に答える 5

7

簡単に試せる方法の 1 つは、Clang 静的アナライザーを実行することです。これにより、コード内で見逃している可能性のある問題の一部が見つかりますが、すべてではありません。コンパイル時にコードをチェックするため、絶対確実というわけではありませんが、ほとんどの明らかな問題をほぼ確実に検出します。

于 2008-11-11T18:52:21.013 に答える
4

また、メモリ モニター インストルメントを使用してアプリケーションを実行し、デバイスのシステム全体の使用状況を確認する必要があります。

于 2008-11-11T22:08:21.147 に答える
2

Leaks は、何からも参照されていないが保持されているメモリのみを検出します。

表示されているのは、メモリが保持されたままで、まだ何かによって参照されているということです。

特に注意すべきことの 1 つは、クラスの参照を別のものにデリゲートとして渡している場合は、dealloc メソッドでそれを解放することです。

同様に、何らかの通知をサブスクライブしている場合は、viewWillDisappear でサブスクライブを解除する必要があります: (View Controller で一般的なサブスクライブ解除方法を使用する場合は、メモリ警告通知を再度サブスクライブすることを忘れないでください。

タイマーも同じように、ビューがなくなると非アクティブになり、ビューが戻ってくると再び有効になります (もちろん、アプリケーションの実行中にタイマーを実行する必要がある場合を除きます)。

基本的に、クラスの参照を与えるものには疑いを持ち、可能な限りそのリンクを削除する方法を見つけようとします (dealloc または viewWillDisappear: またはその両方で)。

于 2008-11-12T03:37:18.097 に答える
2

これが私が学んだことの要約です(いくつかの優れた回答とコメントのおかげです):

  • オブジェクト割り当ては、メモリ使用量と同じではありません。ObjectAlloc の net bytes 要素に関する私の質問に対する答えは、注意を払うべきではないということです。少なくとも、使用しているメモリの量やクラッシュの原因を特定するときは注意が必要です。アプリケーションの実際のメモリ使用量は反映されていません。
  • 私の素人の推測では、ObjectAlloc は、直接オブジェクト自体が占有するメモリのみを表示します。したがって、UIImageView がある場合、さまざまなプロパティを格納するのにほんの数バイトしか必要としませんが、メモリ内の画像を指しているため、大量のスペースが必要になる場合があります。したがって、ObjectAlloc を調べることは、オブジェクトを作成して保持していないことを確認する場合にのみ役立ちます。使用しているメモリの量や、クラッシュする前に使用できる量を知ることはできません。
  • MemoryMonitor は、合計メモリ使用量を示します。[Instruments] ウィンドウの右下にある検索ツールを使用して、アプリの使用状況のみを表示するように制限できます。
  • ObjectAlloc と Memory Monitor (および Leaks ツール) の両方が Instruments のプラグインです。Run -> Start with Performance Tool を実行して、XCode 内から Instruments を起動できます。インストゥルメントに入ったら、ライブラリを開き、新しいプラグインを追加して、パフォーマンスのさまざまな側面を監視できます。
于 2008-11-14T05:13:41.673 に答える
0

探すべきことの1つは、循環参照です。

(私はこれをひいきに聞こえたくありません-私が明確になっていることを確認したいだけです:)オブジェクトaがオブジェクトbを参照し、オブジェクトbがオブジェクトaを参照している場合、すべてのメモリは引き続き参照されますが、これは孤立したオブジェクトの島であり、アプリから分離されており、再利用できません。もちろん、より多くのオブジェクトが含まれる場合があります(abを参照し、bcを参照し、cはaを参照します)。

どこかにオブジェクトのグラフを作成していて、後方参照または相互参照がある場合は、ルートを解放するときに必ず円を壊してください(これを行うにはさまざまな方法があります。最も簡単なのは、おそらく各クラスを確認することです。問題のreleaseAllメソッド、または同様のメソッド(子オブジェクトでreleaseAllを呼び出し、子オブジェクトを解放する)がありますが、これが常に最良のソリューションであるとは限りません)。

于 2008-11-14T09:40:03.710 に答える