4

短いベンチマーク中に GC が起動しないように GC を調整しようとしています。

そのために、若い世代をできるだけ大きく設定し、Eden のサイズよりもガベージを少なくするようにしました。

次のパラメーターを使用しました。

java -Xmx1g -Xms1g -Xmn1g -XX:NewSize=1000m -XX:MaxNewSize=1g -XX:SurvivorRatio=10000 -verbose:gc Main

しかし、なんらかの理由で、VM メモリが 300M しかない場合でも [Full GC] ログが表示されます。JVM チューニングが不足していませんか?

4

3 に答える 3

2

サバイバーの配給は非常に重要です。10000の場合、サバイバースペースはエデンの10000分の1のサイズであるとJVMに伝えます。

ドキュメントから

サバイバースペースが小さすぎる場合、コレクションのコピーはテニュア世代に直接オーバーフローします。サバイバースペースが大きすぎると、無駄に空になります。各ガベージコレクションで、仮想マシンは、オブジェクトが保持される前にオブジェクトをコピーできるしきい値を選択します。このしきい値は、生存者を半分いっぱいに保つために選択されます。コマンドラインオプション-XX:+ PrintTenuringDistributionを使用して、このしきい値と新世代のオブジェクトの経過時間を表示できます。また、アプリケーションの寿命分布を観察するのにも役立ちます。

したがって、明らかにサバイバースペースの比率が非常に低いため、オブジェクトはテニュア世代に直接保存されます。

保有世代がいっぱいになると、主要なコレクションが発生しました。そのため、ログに表示[Full GC...]されます。

若い世代をもっと大きく使いたいなら:

-XX:NewRatio=1

これは、エデンとサバイバースペースの合計サイズが合計ヒープサイズの半分になることを意味します。(私はあなたがより大きな若い世代を持つことはできないと思います)

また、-XX:NewSizeすでに設定している場合は設定する必要はありませんが、1.4以降も同じです。そして、私はあなたが上から若い世代をバインドしたくないと思います、デフォルト値は無制限です。ただし、若い世代のサイズを最大ヒープサイズと同じ値に設定すると、古い世代用のスペースが確保されないため、JVMによって世代のサイズが変更されると思います。-Xmn-Xmn-XX:MaxNewSize

結論として、割り当てがテニュア世代に直接発生する場合もあります。(オブジェクトが古い世代に直接割り当てられることはありますか?

  • 若い世代で割り当てが失敗し、オブジェクトがオブジェクトへの参照を含まない大きな配列である場合は、古い世代に直接割り当てることができます。一部の選択された例では、この戦略は、古い世代から割り当てることによって若い世代のコレクションを回避することを目的としていました。しきい値のサイズは64kワードです。
于 2012-05-16T10:43:58.713 に答える
2

Tenured スペースがいっぱいになったため、完全な GC を取得できます (大きなオブジェクトは Tenured スペースに直接配置されます)。

私は通常、4 ~ 24 GB の eden サイズを試しますが、tenured スペースのサイズが 0.5 ~ 2 GB であることを確認します。

于 2012-05-17T07:22:39.353 に答える
1

多くのオブジェクトの割り当てを解除している場合でも、GC は引き続き実行されます。割り当てられたスペースをすべて使用するまで待機するだけの問題ではありません。実行した場合に深刻な GC ジッターが発生する可能性があります。 .

オブジェクト処理の使用方法と、より効率的にできるかどうかを検討する必要があります。オブジェクト自体の割り当てを解除して置き換えるのではなく、オブジェクトの値を更新することにより、オブジェクトを再利用する方法についてのいくつかのアイデアについては、LMAX ディスラプター パターンを参照してください。

そうは言っても、これは GC のチューニングに関するかなり良い記事です - http://developer.amd.com/documentation/articles/pages/4EasyWaystodoJavaGarbageCollectionTuning.aspx

于 2012-05-16T07:11:40.780 に答える