最適なフリーヒープとトータルヒープの比率はどれくらいですか?この比率のどの値で、ヒープサイズを増やす/ヒープサイズを減らすことを検討する必要がありますか?
3 に答える
理想的な瞬間的な比率は1です。理想的には、JVMは必要なメモリを正確に消費し、それ以上でもそれ以下でもありません。それは到達するのが非常に難しい目標です;)
問題(TNilssonが指摘しているように)は、アプリケーションのメモリ要件が機能するにつれて時間の経過とともに変化することです。そのため、許容できるよりも頻繁に収集/圧縮を引き起こさないように十分なスペースを確保し、消費させたいと考えています。 RAMを追加購入する必要がないほど十分なスペースがありません。
これはおそらく、新しいオブジェクトを割り当てる速度に依存します。ガベージコレクションには、ライブオブジェクトからの参照をトレースする多くの作業が含まれます。十分な空きメモリがある状況(たとえば、500 MBが使用され、500 MBが空き)に対処しているところですが、配列の割り当てが多すぎて、JVMが時間の95%をGCに費やしてしまいます。したがって、実行時のメモリの動作を忘れないでください。
「Javaではオブジェクトの割り当てが非常に速い」などのパフォーマンス調整に関する記事はすべて、一部の割り当てによって1秒のGC時間が発生することは言及されていませんが、私は笑いました。
簡単な答えは1つではありません。2つの例を挙げましょう。
例1-プログラムは起動時に100M相当のメモリを割り当て、その後、残りの実行ではメモリを割り当てません。
この場合、スペースの浪費を避けるために、ヒープサイズを100M(まあ、おそらく101か何かですが、要点はわかります...)にする必要があることは明らかです。
例2-プログラムは1秒あたり10Mのメモリを割り当てます。1秒を超えて保持されるデータはありません。(たとえば、大量の一時データを必要とする計算を実行していて、完了すると単一の整数が返されます...)
正確な数を知ることはおそらくそれほど現実的ではありませんが、それは一例です。
10Mの「ライブ」データがあるため、少なくとも1,000万のヒープが必要になります。それ以外に、ガベージコレクタがどのように機能するかを確認する必要があります。簡単に言うと、GCの完了にかかる時間はO(ライブセット)です。つまり、「デッド」データの量は実際には入力されません。ライブセットサイズが一定の場合、ヒープサイズに関係なくGC時間は一定です。これにより、ヒープが大きくなり、スループットが向上します。
(今、本当に物事を台無しにするために、ヒープの圧縮のようなものを追加すると、画像はさらに不鮮明になります...)
結論 これは問題の単純化されたバージョンですが、簡単な答えは-状況によって異なります。