16

はじめに:

私は次の構造を持つアプリを持っています: 上に ActionBar (ActionBarSherlock) その下に ViewPagerIndicator (タブ用) ViewPager (ホスト Fragments)

フラグメントの 1 つがかなり大きなメモリ リークを引き起こしているという問題があります。問題を次のケースに絞り込みました。

onCreateViewリークの原因となっているフラグメントは、そのメソッドでレイアウトを膨張させるだけです。これは次の方法で行われます。

return inflater.inflate(R.layout.filter_auctions_fragment, container, false);

ここでは珍しいことは何もありません。

レイアウト ファイルにはScrollViewLinearLayoutと 2 つEditTextの のみが含まれています (通常はより多くのものが含まれていますが、単純にするために問題をこれらのビューだけに絞り込みました)。

次に、フラグメントを追加するために使用されるコード: mTab​​sAdapter.addTab(tabName, ProblematicFragment.class);

mTabsAdapterサポート ライブラリTabsAdapterを拡張するクラスである のインスタンスです。FragmentPagerAdapterかなり標準的なので、この質問をできるだけ短くするためにソースを含めていません。

今面白い部分:

これは、デバイスを数回前後に回転させると、ヒープで何が起こるかです:

12-28 12:26:27.180: D/dalvikvm(18841): GC_CONCURRENT freed 530K, 7% free 10701K/11436K, paused 4ms+7ms, total 58ms
12-28 12:26:27.180: D/dalvikvm(18841): WAIT_FOR_CONCURRENT_GC blocked 24ms
12-28 12:26:28.270: D/dalvikvm(18841): GC_CONCURRENT freed 737K, 8% free 11048K/11964K, paused 4ms+5ms, total 53ms
12-28 12:26:29.510: D/dalvikvm(18841): GC_CONCURRENT freed 789K, 8% free 11464K/12436K, paused 5ms+5ms, total 42ms
12-28 12:26:30.640: D/dalvikvm(18841): GC_CONCURRENT freed 888K, 9% free 11919K/12984K, paused 4ms+5ms, total 52ms
12-28 12:26:31.810: D/dalvikvm(18841): GC_CONCURRENT freed 903K, 8% free 12421K/13500K, paused 3ms+8ms, total 58ms
12-28 12:26:33.800: D/dalvikvm(18841): GC_CONCURRENT freed 1092K, 9% free 13005K/14272K, paused 4ms+6ms, total 59ms
12-28 12:26:33.800: D/dalvikvm(18841): WAIT_FOR_CONCURRENT_GC blocked 20ms
12-28 12:26:36.000: D/dalvikvm(18841): GC_CONCURRENT freed 1355K, 11% free 13518K/15048K, paused 3ms+8ms, total 74ms
12-28 12:26:36.000: D/dalvikvm(18841): WAIT_FOR_CONCURRENT_GC blocked 19ms
12-28 12:26:38.110: D/dalvikvm(18841): GC_CONCURRENT freed 1450K, 11% free 14106K/15720K, paused 3ms+11ms, total 72ms
12-28 12:26:40.450: D/dalvikvm(18841): GC_CONCURRENT freed 1530K, 11% free 14807K/16516K, paused 2ms+15ms, total 75ms
12-28 12:26:40.450: D/dalvikvm(18841): WAIT_FOR_CONCURRENT_GC blocked 29ms
12-28 12:26:43.030: D/dalvikvm(18841): GC_CONCURRENT freed 1682K, 11% free 15591K/17452K, paused 3ms+10ms, total 66ms
12-28 12:26:43.030: D/dalvikvm(18841): WAIT_FOR_CONCURRENT_GC blocked 32ms

明らかに、メモリ リークです。はい、アクティビティが最初から再作成されることはわかっています。横向きモードと縦向きモードのレイアウトが異なるため、これが必要です。それでも、メモリ リークが発生することはありません。

この問題の原因を見つけました。それは、EditText先に述べた 2 つの です。それらをレイアウトから削除して同じテストを行うとすぐに(前後に回転します)。これらは私が得るGCメッセージです:

12-28 12:21:41.270: D/dalvikvm(17934): GC_CONCURRENT freed 534K, 7% free 10853K/11576K, paused 3ms+7ms, total 44ms
12-28 12:21:42.560: D/dalvikvm(17934): GC_CONCURRENT freed 818K, 9% free 11113K/12108K, paused 11ms+9ms, total 95ms
12-28 12:21:44.680: D/dalvikvm(17934): GC_CONCURRENT freed 1036K, 10% free 11313K/12528K, paused 3ms+6ms, total 54ms
12-28 12:21:44.680: D/dalvikvm(17934): WAIT_FOR_CONCURRENT_GC blocked 15ms
12-28 12:21:47.420: D/dalvikvm(17934): GC_CONCURRENT freed 1089K, 10% free 11510K/12780K, paused 2ms+6ms, total 79ms
12-28 12:21:47.420: D/dalvikvm(17934): WAIT_FOR_CONCURRENT_GC blocked 39ms
12-28 12:21:50.200: D/dalvikvm(17934): GC_CONCURRENT freed 1317K, 12% free 11461K/12956K, paused 4ms+13ms, total 84ms
12-28 12:21:53.210: D/dalvikvm(17934): GC_CONCURRENT freed 1629K, 14% free 11148K/12956K, paused 3ms+7ms, total 47ms
12-28 12:21:55.580: D/dalvikvm(17934): GC_CONCURRENT freed 1056K, 13% free 11302K/12956K, paused 4ms+7ms, total 59ms
12-28 12:21:57.280: D/dalvikvm(17934): GC_CONCURRENT freed 1306K, 14% free 11200K/12956K, paused 5ms+5ms, total 82ms
12-28 12:21:59.420: D/dalvikvm(17934): GC_CONCURRENT freed 1035K, 12% free 11408K/12956K, paused 3ms+7ms, total 55ms
12-28 12:22:01.990: D/dalvikvm(17934): GC_CONCURRENT freed 1392K, 13% free 11352K/12956K, paused 4ms+9ms, total 54ms
12-28 12:22:01.990: D/dalvikvm(17934): WAIT_FOR_CONCURRENT_GC blocked 30ms

今、それが私が見たいものです!

どうして!?

なぜこれが起こっているのか誰か教えてもらえますか?これらのオブジェクトへの参照をアプリのどこにも保持していないことを追加したいと思いEditTextます (通常は保持していますが、テスト目的でそれらをすべて削除しても、リークは発生します)。

おまけ - MAT リークのスクリーンショット:

アクティビティの GC ルートへのパス (ソフト/弱い参照を除く)

私のGCルートへのパス(ソフト/弱い参照を除く)

ご覧のとおり、フラグメントとアクティビティには 16 個のインスタンスがありますが、1 つしかないはずです。

編集:

FragmentManager.beginTransaction()別のアクティビティに(を使用して)フラグメントを手動で追加すると、リークが発生しないことに気付きました!!! 私は今完全に混乱しています...

EDIT2:

android:ids の属性を削除するEditTextと修正されます...しかし、今ではそれらはかなり役に立ちません...

4

2 に答える 2

0

Samsung Galaxy S3 でもまったく同じ問題に直面していました。

@aslakjoの解決策はうまくいきませんでした。私はすでに提案を無効にしていました

最後に、XML レイアウトの をandroid:idbyに置き換えました。ビューページャーに含まれていたフラグメントは、表示されなくなったときに正しくガベージコレクションされます。理由は聞かないでください。android:tagEditText

このデバイスは、の存在に基づいて何かを登録する可能性がありidます。

于 2014-12-01T15:37:42.360 に答える