さて、ここにはいくつかの質問があります!
1-存続期間の短いオブジェクトはどのように管理されますか?
前述のように、JVMは弱い世代仮説に従うため、大量の短期間のオブジェクトを完全に処理できます。
メインメモリ(ヒープ)に到達したオブジェクトについて話していることに注意してください。これは常にそうであるとは限りません。作成したオブジェクトの多くは、CPUレジスタを残しさえしません。たとえば、このforループを考えてみましょう
for(int i=0, i<max, i++) {
// stuff that implies i
}
ループ展開(JVMがコードで頻繁に実行する最適化)について考えないでください。max
がに等しい場合Integer.MAX_VALUE
、ループの実行には時間がかかる場合があります。ただし、i
変数がループブロックをエスケープすることはありません。したがって、JVMはその変数をCPUレジスタに入れ、定期的にインクリメントしますが、メインメモリに送り返すことはありません。
そのため、何百万ものオブジェクトをローカルでのみ使用する場合、それらを作成することは大したことではありません。それらはエデンに保管される前に死んでいるので、GCはそれらに気付くことさえありません。
2-GCのオーバーヘッドを減らすことは有用ですか?
いつものように、状況によります。
まず、何が起こっているのかを明確に把握できるように、GCロギングを有効にする必要があります。で有効にでき-Xloggc:gc.log -XX:+PrintGCDetails
ます。
アプリケーションがGCサイクルで多くの時間を費やしている場合は、はい、GCを調整します。それ以外の場合は、実際には価値がない場合があります。
たとえば、100ミリ秒ごとに10ミリ秒かかる新しいGCがある場合、時間の10%をGCに費やし、1秒あたり10個のコレクションがあります(これはハウウージです)。そのような場合、10のGC /秒がまだ存在するため、GCのチューニングに時間を費やすことはありません。
3-ある程度の経験
特定のクラスを大量に作成しているアプリケーションでも同様の問題がありました。GCログで、アプリケーションの作成速度が約3 GB /秒であることに気づきました(これは、1秒あたり3ギガバイトのデータです!)。
問題:作成されているオブジェクトが多すぎるために頻繁に発生するGCが多すぎる。
私の場合、私はメモリプロファイラーをアタッチし、クラスがすべてのオブジェクトの大きな割合を占めていることに気付きました。インスタンス化を追跡して、このクラスが基本的にオブジェクトにラップされたブール値のペアであることを確認しました。その場合、2つのソリューションが利用可能でした。
2番目の方法を選択したのは、それがアプリケーションへの影響が最も少なく、導入しやすいためです。スレッドセーフではないキャッシュを備えたファクトリを配置するのに数分かかりました(最終的に4つの異なるインスタンスしかなかったため、スレッドセーフは必要ありませんでした)。
割り当て率は1 GB /秒に低下し、若いGCの頻度も低下しました(3で除算)。
お役に立てば幸いです。