次のコードを見てください
for(int i = 0; i < 10; i++) {
new Object();
}
オブジェクトへの参照がないため、ガベージ コレクターは反復ごとに起動しますか? 通常、参照なしで繰り返しオブジェクトを作成することはお勧めできませんか?
次のコードを見てください
for(int i = 0; i < 10; i++) {
new Object();
}
オブジェクトへの参照がないため、ガベージ コレクターは反復ごとに起動しますか? 通常、参照なしで繰り返しオブジェクトを作成することはお勧めできませんか?
オブジェクトへの参照がないため、ガベージコレクターはすべての反復でキックしますか?
おそらくそうではありません。JVMが一般的にそのように参照カウントされるわけではありません。少量のガベージが作成されます。各オブジェクトは反復後に収集の対象になりますが、それらのオブジェクトが実際に収集されるタイミングは指定されていません。
通常、参照なしでオブジェクトを繰り返し作成することはお勧めしませんか?
通常、目的のないオブジェクトを作成することはお勧めできません。「参照なし」とはどういう意味かわかりません。各反復で新しいオブジェクトを作成する理由があり、反復が完了した後にそれが必要ない場合は、それで問題ありません。
Javaは、ガベージコレクションがいつ開始されるかについては保証しません。GCに関しては1つの保証しかありません(ここで言い換えると)。
最終的に、refcountがの範囲外のオブジェクトは
0
ガベージコレクションされます。
電話をかけSystem.gc()
ても何も保証されません。非決定論的な動作に依存するコードには近づかないでください。
Jon Skeetが指摘したように、ほとんどのJavaGCは参照カウントを使用しません。詳細については、http://www.ibm.com/developerworks/java/library/i-garbage2/およびここhttp://www.ibm.com/developerworks/java/library/i-garbage1/を参照してください(記事は約IBM VM-他のVMはGCアルゴリズムが異なる場合があります)。私は主に用語を過度に単純化するために使用していました。
いいえ、ガベージコレクターはすべての反復で起動するわけではありません。コレクターは正確に決定論的ではありません-コレクターを実行させる特定の制約のセットはありません。ガベージコレクターは、収集できるオブジェクトを作成したという理由だけで実行されるわけではありません。
ただし、各反復で作成されたオブジェクトは、すぐにガベージコレクションの対象になります。これらは2つの異なる概念です。
GCがいつ実行されるかはわかりません。
ループ内のヒープ上に作成したすべてのオブジェクトは、スコープ外になるとGCの対象になりますが、反復ごとにGCを実行することが保証されているわけではありません。
ガベージコレクターは、コードブロックが終了したときではなく、世代がいっぱいになったとき(または特定の占有率で)に起動します。
ガベージコレクションが短命のオブジェクト用に最適化されているというコメントは有効です。
さらに、この場合、ガベージコレクションにも影響を与える可能性のあるHotSpotの側面があることに注意してください。
エスケープ分析は、Java6のOracle/ OpenJDK JVMに追加され、OpenJDK7のHotSpotコンパイラでデフォルトで有効になっています。
エスケープ分析は、Java Hotspot Serverコンパイラが新しいオブジェクトの使用範囲を分析し、それをJavaヒープに割り当てるかどうかを決定するための手法です。
理論的には、これによりコンパイラはオブジェクトがメソッド内でのみアクセス可能であると判断できるため、ヒープではなくスタックに割り当てることができます。そのため、ガベージコレクションをまったく必要とせずに、各反復の最後にメモリから解放できます(各反復後に明示的にC / C ++のメモリを解放するのと同様です)。
実際には、OpenJDK 7のエスケープ分析のドキュメントには、JDK7コンパイラは現在「ヒープ割り当てを非グローバルにエスケープするオブジェクトのスタック割り当てに置き換えない」と記載されています。したがって、スタック割り当ては実装可能な最適化(IMO)であるように見えますが、現在は実装されていないようです。
もう1つの最適化は、コンパイラー(またはHotSpot)が、この例で作成されたオブジェクトが使用されないこと、およびそのコンストラクターがアプリケーションの他の場所で状態/原因の副作用を変更しないことを検出することです。その場合、コンパイルされたコードからステートメントを完全に削除する可能性があるため、new Object()
実行されることはありません。
要約すると、HotSpotはさらにスマートになり、このような場合にすでにいくつかの最適化が行われています。
現在(他の人が言及しているように)GCが各反復の直後に開始する可能性は低いですが、それでもこれらのオブジェクトをすばやく解放する可能性があります(エデンスペース/若い世代など)。
将来、HotSpotはスタック割り当てを使用する可能性があるため、各反復後に実際にメモリを解放します。または、コンパイラまたはHotSpotは、この特定のステートメントを完全に削除する場合があります。
ガベージ コレクターは反復ごとに開始されますか
これらのオブジェクトは若い世代にあり、その領域のクリーンアップは高速であるため、気にする必要はありません (小規模なハウスキーピングが必要です)。
通常、参照なしで繰り返しオブジェクトを作成することはお勧めできませんか?
依存します。そのような場合、つまり、ローカルスコープで匿名オブジェクトを作成すると、GC がそれらを GC の対象として識別するのに実際に役立ちます。