4

私のAndroidアプリは、時間の経過とともにますます多くのメモリを消費しています。ヒープ ダンプを取得し、MAT で分析しました。

主なリーク容疑者は次のとおりです。

そのため、アプリを終了した後 ([戻る] ボタンを使用) にアクティビティの 1 つがメモリから消去されていないようで、アプリを再起動すると、新しいインスタンスが作成されてメモリがいっぱいになります。

それらが PhantomReferences の場合、しばらくしてから、またはアプリを終了したときにメモリがクリアされないのはなぜですか? 他のアプリなどを使用してもメモリがクリアされることはありません。アプリを完全に閉じる唯一の方法は、タスクマネージャーを使用してアプリを手動で強制終了することです。

このアナーキーなメモリ消費を避けるにはどうすればよいですか?

編集:

問題が見つかりました!各アクティビティは Thread.setDefaultUncaughtExceptionHandler() を使用して CustomExceptionHandler を設定し、その CustomExceptionHandler はコンテキストへの参照を保持していました。そのため、コンテキスト参照を取り除き、onDestroy() メソッドの DefaultUncaughtExceptionHandler を「null」にしました。それはもう本当に良くなりました!

4

2 に答える 2

5

私が一般的に従うアプリのサイズを縮小するためのいくつかの一般的なアプローチは次のとおりです。

  • Intent を次のアクティビティに渡す下で finish() を呼び出します。これにより、スタックの積み上げが回避され、gc (ガベージ コレクション) に役立ちます。
  • 共有設定を使用してデータを保存していない場合は、終了時に System.exit() を呼び出してそれらをフラッシュします。
  • 最終的なプログラムで使用していないドローアブル イメージ/レイアウト xml/Java クラスが見つかった場合は、それらをプロジェクトから削除してください。
  • JPEG 画像は大量のメモリを消費するため、画像は .png である必要があります。
  • データベース(sqlite、内部データベースなど)を使用する場合、より良いアプローチは「try/catch/finally」ブロックを使用することです。データベースを開こうとすると、最後にデータベースを閉じます。これにより、そうでないために引き起こされるメモリリークが回避されますカーソルまたはデータベースを閉じます。
  • スレッドの代わりに AsyncTask を使用します。onPostExecute() 関数で、進行状況ダイアログがあれば閉じます。
于 2012-06-20T10:13:53.470 に答える
5

MAT のドミネーター ツリー機能を使用して、それらの参照の上にあるものを見つけます。これにより、どれActivityが原因であるかがわかります。

どこにもa を渡して参照を保持していないことを確認してくださいContext。これは古典的な Android のメモリ リークであり、非常に簡単に実行できます。

一部の静的解析ツールはこれに難色を示していますが、onDestroy()メソッドでActivitynullすべてのローカル変数 (プリミティブを除く) を使用できます。ガベージ コレクターを微調整するのに役立ち、MAT でのヒープ ダンプの解析を容易にすることができます。

于 2012-06-20T10:21:35.240 に答える