16

これはばかげた質問かもしれませんが、私の経歴はC++と自分の記憶の管理にあります。

私は現在、ガベージコレクションと知覚される「ラグ」の頻度を減らすために、ゲームの1つから可能なすべての割り当てを削減しているため、作成するすべての変数について、オブジェクト(StringやRectなど)を使用します。コンストラクターで事前に作成し、単純な10行の関数で一時変数を作成しないようにしています...(それが理にかなっていることを願っています)

とにかく今夜はもう少し作業していましたが、ガベージコレクションとプリミティブ型(int、boolean、float)は、呼び出される10行の関数で作成するこれらのプリミティブ型変数であるという仮定について完全に間違っている可能性があることに気付きました。ガベージコレクションの問題に1秒間に20回追加しますか?

したがって、1年前、数秒ごとにlogcatに次のようなメッセージが表示されます。

GCは101msで4010オブジェクト/484064バイトを解放しました

今、私はそのメッセージを15-90秒かそこらごとに見ます...

だから私の質問を言い換えると:このメッセージを見たときにプリミティブ型(int、float、booleanなど)が含まれていますか?

4

3 に答える 3

25

プリミティブ型はオブジェクトではないため、ガベージコレクションは発生しません。ただし、ボックス化により、プリミティブ型は明示的に指定しなくても簡単にオブジェクトになる可能性があるため、十分に注意する必要があります。

たとえば、整数キーのHashMap <>が必要な場合は、HashMapを使用します。「int」はオブジェクトではないため、コンテナでは使用できないことに注意してください。整数は、プリミティブintのオブジェクトバージョンです。このようなコードを書くと、整数オブジェクトが自動的に作成されます。

HashMap<Integer, Object> map = new HashMap<Integer, Object>();
int someNum = 12345;    // no object created.
map.put(someNum, null); // Integer object created.

ジェネリックを使用しない場合もまったく同じことが起こりますが、さらに隠されていることに注意してください。

HashMap map = new HashMap();
int someNum = 12345;    // no object created.
map.put(someNum, null); // Integer object created.

この特定の状況では、プリミティブ整数キーのコンテナーであるAndroidのSparseArrayクラスを使用できます。

于 2010-03-19T05:14:41.913 に答える
6

答えはノーのようです。プリミティブはヒープではなくJavaのスタックに配置され、オブジェクトのみがガベージコレクションされるようです。私はこれについての短い参照をたくさん見つけました、ウィキペディアをチェックしてください。少し重い読み物については、JVMガベージコレクションの実装に関する論文を参照してください。プリミティブは物理的に別々のメモリ位置に格納されるため、ここで誤ってガベージコレクションに含まれることはありません。スキミングしたい場合は、4ページで最も直接説明されています。

これは、gcがポインターのみをスキャンし、それをどのようにチェックするかを示すAndroid固有のスレッドです。

于 2010-03-19T03:04:01.073 に答える
2

[注:私はまだ完全なコメント権限を持っていないので、これを別の回答として追加します。]

プリミティブはヒープではなくJavaのスタックに配置され、オブジェクトのみがガベージコレクションされるようです。

これは正確ではありません。プリミティブは、ローカル変数に保持することも、クラスの静的フィールドまたはインスタンスフィールドとして保持することもできます。後者の場合、それらは実際にヒープに格納されますが、重要なことに、それらは独自の「ライフ」を持たず、特に、それらが含まれているオブジェクトとは別にgcされません。

Androidは標準のスタックベースのJVMを実行せず、独自のレジスタベースのVMを備えています。

これは本当の声明ですが、少し誤解を招きやすく、元の質問の要点を超えています。実際、あるメソッドが別のメソッドを呼び出すと(など)、これらのメソッドのアクティベーションフレームはDalvik実装のスタックに格納されます。違いは、アクティベーションフレームを個別に見ると、Dalvikアクティベーションフレームには可変サイズのスタックが含まれていないことです。この点で、Dalvikがアクティベーションフレームを配置する方法は、従来のCのような言語(CやC ++など)での処理方法に似ています。

于 2011-05-05T23:43:15.293 に答える