私のアプリの単純化されたバージョンには、A と B の 2 つのアクティビティがあります。アクティビティ A は B を開始し、いくつかの作業の後、B は finish() を呼び出します。ほとんどのデバイス (4.2 を実行する Galaxy Nexus、4.0.4 を実行する Droid 4、および 2.3.4 を実行する Droid 2) でメモリ アナライザー ツールを使用しても、アクティビティ B の痕跡は表示されません。
しかし、4.1.1 を実行している Samsung S3 では、次の GC ルートへのパス (弱い/ソフト参照は除外) により、MAT はアクティビティ B オブジェクトを表示します。
Class Name | Shallow Heap | Retained Heap
-------------------------------------------------------------------------------------------------
com.myCo.myApp.ActivityB @ 0x42720818 | 264 | 3,280
|- <Java Local> java.lang.Thread @ 0x4271cf60 Thread-21941 Thread| 80 | 52,264
|- mOuterContext android.app.ContextImpl @ 0x426adf68 | 104 | 784
| '- mContext android.media.AudioManager @ 0x428e49a0 | 48 | 152
-------------------------------------------------------------------------------------------------
アクティビティ B を開始および停止するたびに、MAT はアクティビティ B のメモリ フットプリントの別のインスタンスを表示します。また、アクティビティ B を開いたり閉じたりするほど、logcat で報告されるメモリ フットプリントが大きくなります。MAT を使用して GC を強制しても、アクティビティ B メモリへの参照は削除されません。
3 つの質問があります。
デバイスによってメモリ/GC の動作が異なるのはなぜですか?
S3 では、OS は最終的に戻ってきて、取り残されたアクティビティ B オブジェクトを GC します (つまり、Android がクラッシュする前にクリーンアップするので、心配する必要はありません)。
そうでない場合、Thread と AudioManager の参照はどこから来ているのですか?どうすればクリアできますか?
経験豊富な「リークハンター」に感謝します!