3

私はかなりの量のガベージを生成するアプリを書いていますが、メモリ制限に達するほどではありません。つまり、ガベージが発生しても、ガベージを収集する必要はありません。しかし、これにもかかわらず、また、使用可能なメモリ全体のごく一部が使用されているという事実にもかかわらず、ガベージ コレクタが常に呼び出され、アプリケーションが遅れています。

この出力からわかるように、使用可能なメモリの 2% しか使用していませんが、ガベージ コレクターは常に実行されています。

12-22 04:36:08.219: D/dalvikvm(12033): WAIT_FOR_CONCURRENT_GC blocked 61ms
12-22 04:36:08.359: D/dalvikvm(12033): GC_CONCURRENT freed 1012K, 98% free 11865K/405196K, paused 4ms+13ms, total 73ms
12-22 04:36:08.359: D/dalvikvm(12033): WAIT_FOR_CONCURRENT_GC blocked 38ms
12-22 04:36:08.479: D/dalvikvm(12033): GC_CONCURRENT freed 1020K, 98% free 11862K/405196K, paused 3ms+13ms, total 66ms
12-22 04:36:08.479: D/dalvikvm(12033): WAIT_FOR_CONCURRENT_GC blocked 36ms
12-22 04:36:08.649: D/dalvikvm(12033): GC_CONCURRENT freed 1015K, 98% free 11863K/405196K, paused 2ms+16ms, total 78ms
12-22 04:36:08.649: D/dalvikvm(12033): WAIT_FOR_CONCURRENT_GC blocked 66ms
12-22 04:36:08.789: D/dalvikvm(12033): GC_CONCURRENT freed 1017K, 98% free 11861K/405196K, paused 2ms+13ms, total 66ms
12-22 04:36:08.789: D/dalvikvm(12033): WAIT_FOR_CONCURRENT_GC blocked 58ms

この不必要なガベージ コレクションを完全に回避することは、アプリの成否を左右します。

十分な空きメモリがあるのにガベージ コレクタが実行されるのはなぜですか? 絶対に必要になるまでガベージコレクターを実行しないようにする方法はありますか? また、ルート化された電話で実行していることにも言及する必要があります。

ありがとう!

編集:うーん..工場やさまざまな手法を使用してすべてのゴミを排除しようとしてきましたが、まだかなりの量が生成されており、フォーム s1 + s2 + s3 の文字列連結が原因だと思います。このような式を、各コンポーネントへの参照を保存できる形式に変換しましたが、気密性があるかどうかはわかりません。次の行でゴミが生成されているのがわかりますか?

String ss1 = input.substring(m, m+k1);
String ss2 = ss1 + possible_perturbations1.charAt(p1);
String ss3 = input.substring(m+k1+1, m+k2);
String ss4 = ss2 + ss3;
String ss5 = ss4 + possible_perturbations2.charAt(p2);
String ss6 = input.substring(m+k2+1, m+i+1);
String current_str = ss5 + ss6;

allStrs.add(ss1);
allStrs.add(ss2);
allStrs.add(ss3);
allStrs.add(ss4);
allStrs.add(ss5);
allStrs.add(ss6);
allStrs.add(current_str);

いくつかの注意点: ほとんどの標準ライブラリ コンテナーの remove 関数はガベージを生成します。また、String、Integers、Double などの一時変数を生成するオブジェクト間のほとんどのバイナリ操作も同様です。明確にする。

4

3 に答える 3

3

あなたのコードがなければ、ガベージコレクターが呼び出されている理由を言うのは簡単ではありません。エラーではありませんが、メモリチャンクが空いている場合はGCの義務です。

ガベージ コレクターは、作成されて使用されなくなったオブジェクトがある場合にアクティブになります。

GC に遅れを取らない最善の方法は、ガベージを常に収集する必要をなくすことです。たとえば、オブジェクトを無効にして新しいオブジェクトを作成する代わりに、オブジェクトを再利用できます。

しかし参考までに、ガベージ コレクターの実行を停止することはできません。

于 2012-12-22T09:55:05.820 に答える
0

ガベージ コレクタは、必要なときにいつでも実行されます。ガベージ コレクタを停止する方法はありません。ガベージ コレクタを呼び出す実際の方法さえありません。ガベージ コレクタが実行されるかどうかを尋ねるだけですが、それでも実行されない可能性があります。

ガベージ コレクタは、メモリ不足のときに実行されるだけでなく、常に「OutOfMemory」例外を回避しようとします。私の知る限り、GC は一定の間隔で実行され、スコープ内で不要になった変数を調べます。

Sahil Mahajan Mj が既に述べたように、最善の方法はオブジェクトを再利用することです。これにより、ガベージ コレクターの実行が妨げられることはありませんが (前述のように、いずれにせよ実行されます)、GC が多くのことを行わないようにすることができます (これにより時間が節約されます)。

于 2012-12-22T10:26:58.997 に答える
0

アプリが使用可能なヒープ メモリのほんの一部を使用している場合でも、Android の GC が実行されるのは正常です。

考えられる理由の 1 つは、数ミリ秒の長い GC 実行の方が、数秒の長い GC 実行 (ユーザーが気付く) よりも優れていることです。

ごみはどうやって作っているのですか?ほとんどの場合、一定数のオブジェクトのみを作成して再利用できます (おそらくオブジェクト プールを介して)。

自分が何をしているのかを 100% 確信しており、より良い解決策が存在しない場合は、ガベージ オブジェクトへの参照を保持して、GC がそれらを削除しないようにすることができます。しかし、ほとんどの場合、これを実行したくありません。

アップデート:

通常、文字列の連結を避け (すべての連結で新しいオブジェクトが作成されます)、代わりに StringBuilder を使用する必要があります。

String abc = a + b + c; // Wrong
String abc = new StringBuilder(a).append(b).append(c).toString(); // Right
于 2012-12-22T10:23:16.860 に答える