8

メモリ不足の警告に応答して大量のメモリを解放した後でも、メモリ使用量が原因で iOS がアプリ (iPad、iOS 4) を終了する理由がわかりません。たとえば、これは典型的な終了シナリオで、頻繁にメモリ使用量を記録しています。各行の最初の KB 値である「アプリ」の使用量を見てください。

...
2011-12-14 13:25:42.343 Oyster[211:707] Memory usage (KB): app 268256, delta 6472, used 366800/373940
2011-12-14 13:25:43.292 Oyster[211:707] Memory usage (KB): app 273900, delta 5644, used 372444/381024
2011-12-14 13:25:44.159 Oyster[211:707] Memory usage (KB): app 282920, delta 9020, used 381464/389116
2011-12-14 13:25:45.184 Oyster[211:707] Memory usage (KB): app 272140, delta -10780, used 370684/379432
2011-12-14 13:25:46.109 Oyster[211:707] Memory usage (KB): app 260412, delta -11728, used 358956/365900
2011-12-14 13:25:48.443 Oyster[211:707] Received memory warning. Level=2
2011-12-14 13:25:48.454 Oyster[211:707] Memory usage (KB): app 9172, delta -251240, used 107716/112548
(gdb)

メモリ警告が表示されるまで、アプリのメモリ使用量が増加していることがわかります。次に、メモリの警告に正しく応答し、大量のメモリ (250MB!) を解放します。その時点で私のアプリは終了し、iOS は iPad のホーム画面に移動します。

ここの「メモリ使用量」ログは、この回答のコードに基づくlogMemoryUsage() 関数で表示されます。

記録のために、SDWebImage を使用してUIImageをメモリにキャッシュしていますが、示されているように、キャッシュを空にすることでメモリ警告を処理します (この時点ではかなり大きい)。SDWebImage のキャッシングを微調整して、使用可能なメモリをすべて使用しないようにし、メモリの警告を待つだけでよいことはわかっていますが、それには次のような疑問が生じます...

大量のメモリを喜んで解放してメモリ警告に応答しているのに、iOS がアプリを終了させるのはなぜですか?

4

5 に答える 5

11

これは、メモリ管理などに関する優れたプラクティスに対する一般的な回答のようなものです。一般的に、メモリ内キャッシュが大きくなりすぎて、メモリ警告に応答してオブジェクトを解放したとしても、その時までには手遅れのように聞こえます。

  1. メモリ警告は本質的に「悪い」ものではなく、避けることはできません。これらは iOS ライフサイクルの通常の部分であり、アプリが責任を持って動作することを保証するために、すべてのオブジェクトのすべての重要でないデータを解放することによって、それらを正しく処理する必要があります。アプリのフットプリントが小さい場合でも、問題のデバイスの他の状態 (使用中の他のアプリなど) のメモリ警告 b/c を受け取ることができます。ここではランタイム通知について言及していますUIApplicationDidReceiveMemoryWarningNotification。デバッガー メッセージ (例: 「Received memory warning. Level=2」) はアプリに固有のものですが、ランタイム通知の受信と必ずしも相関するとは限りません。

  2. についてはよくわかりませんSDWebCache。実装を見て、メモリが効率的に解放されていることを確認します。たとえば@autoreleasepool、関連する場所で使用すると、実行ループ内でオブジェクトをより効率的に解放するのに役立つかもしれません。

  3. アプリのインメモリ フットプリントをできるだけ抑えるように努める必要があります。画像データにメモリ内キャッシュを使用しても問題ありませんが、そのサイズを制限します。アプリのフットプリントが 250MB を超えても、メモリの警告を処理したとしても、アプリが終了しても不思議ではありません。それまでには遅すぎる可能性があります。

  4. 終了の原因/原因となる他の問題が発生する可能性があります。コメントが示唆しているように、リークや不正なアクセスなどを探すために、インストゥルメントでさらにデバッグを行う必要があります。ここにクラッシュ ログを投稿すると役に立ちます。

于 2011-12-16T19:51:30.230 に答える
1

詳細情報がないと、これらがあなたに当てはまるかどうかはわかりませんが、メモリの警告をクリーンアップしようとした後、一般的に特定の問題が発生しました。

  • 不明な循環参照は、メモリが期待どおりに解放されるのを防ぎます。Instrumentsを使用してそれらを探します。最近、ブロック内で誤って自分自身を使用していて、保持を引き起こしていたケースを修正しました。メモリの警告があったときに気づき、そのリソースを解放しても警告からうまく回復できませんでした。
  • リソースのクリーンアップ(またはリソースの自動リリース)により、まだ必要なものがリリースされました。あなたはそれを予期しないところにnilを持っているかもしれません、あるいはあなたはゾンビを操作するかもしれません。あなたの保持とクリーンアップ、特に代表者の無力化をチェックしてください。ゾンビと例外ブレークポイントをオンにします。

通常、最善の解決策は、最初からメモリ警告が発生しないようにすることです。

于 2011-12-14T22:29:23.390 に答える
1

大きな画像 (画像ごとに 4Mb) を扱う場合、メモリ不足の警告を受けずにメモリ不足になる危険性があります。

最善の方法は、メモリ使用量が増えすぎないようにすることです。画像の読み込み速度は、キャッシングが適切ですが、実際には必要ないほどです。メモリを使用しなくなったらすぐにメモリを解放して、使用量を抑える方がはるかに優れています。

頑張ってください。共有する価値のあるものを見つけたらお知らせください。

于 2011-12-23T13:27:44.660 に答える
1

レベル 2 のメモリ警告は緊急です。アプリは、レベル 2 の警告を受け取る前に 1 つまたは複数のレベル 1 の警告を受け取る可能性があり、その時点で対処する必要があります。

私の経験では、アプリがレベル 2 の警告を受け取ると、ほとんどの場合手遅れであり、とにかく強制終了されます。

于 2011-12-22T23:51:17.357 に答える
1

画像変換のコードを確認してください。SDWebImage プロジェクトには、選択した画像に変換と回転の手法を適用する画像を縮小するために使用されるコードがいくつかあります。実際には、サイズを縮小するためにあまり使用されませんが、メモリ警告が発生することがあります。そのコードにコメントして、アプリケーションをビルドしてみてください。

アプリで同じ問題が発生しました。変換のコードをコメントしようとしました。問題は解決しました。試してみることもできます。

于 2011-12-22T15:37:41.157 に答える