3

私の作業環境には、WindowsServer2008ハードウェアで実行されるエンタープライズJavaアプリケーションがいくつかあります。外部コンサルタントがJavaアプリケーションのパフォーマンスを確認しており、初期メモリ値と最大メモリ値を同じに変更することを提案しています。

そのため、現在、初期メモリが1GB、最大メモリが2GBのアプリケーションを実行しています。彼らの推奨は、初期メモリと最大メモリの両方を2GBに変更することです。

彼らの推論は2つあります...

  1. 初期値と最大値を2GBに割り当てることにより、Javaアプリケーションが起動すると、2GBのメモリブロックがまっすぐに取得されます。これにより、他のアプリケーションがこのメモリブロックにアクセスできなくなり、このメモリは常にJavaアプリケーションで使用できるようになります。これは、最初のブロックが1GBのみになるという現在の状況とは対照的です。つまり、他のアプリケーションがサーバー上の残りの使用可能なメモリを消費し、エンタープライズJavaアプリケーションが2GBのメモリに拡張できない可能性があります。最大。
  2. Javaが初期サイズと最大サイズの間にメモリを割り当てる必要があるたびに、パフォーマンスがわずかに低下します。これは、Windowsに移動し、必要なサイズの新しいブロックを割り当ててから使用する必要があるためです。このパフォーマンスの低下は、初期サイズと最大サイズの間にメモリが必要になるたびに発生します。したがって、両方を同じ値に設定すると、このパフォーマンスへの影響が排除されます。

彼らの最初のポイントは、他のアプリケーションがサーバー上で何をしているかに関係なく、Javaアプリケーションが常に最大メモリにアクセスできることを意味するため、安全性の観点から有効だと思います。ただし、これは、他のアプリケーションが必要な場合に使用できない大きなメモリブロックがあり、一般的なサーバーパフォーマンスの問題を引き起こす可能性があるため、これはマイナスの点になる可能性もあると思います。

ポイント2で説明しているパフォーマンスへの影響はおそらくごくわずかであるため、心配する価値はないと思います。パフォーマンスに関心がある場合は、メモリのブロックを割り当てることによるパフォーマンスへのわずかな影響を心配するよりも、Javaのガベージコレクションの側面などを調整する方がよいでしょう。

初期メモリと最大メモリを同じ値に割り当てるというリクエストに実際のメリットがあるかどうかを教えてください。どちらの方法でも一般的な推奨事項はありますか?

4

4 に答える 4

3

IMO、最初の提案でさえそれほど重要ではありません。最新のOSには仮想メモリがあります。したがって、Javaプロセスに2GBのメモリを割り当てたとしても、これらの2GBのメモリが常に物理メモリに存在するという保証はありません。同じボックス内に大量のメモリを消費する他のアプリケーションがある場合、メモリをいつ割り当ててもパフォーマンスが低下します。

于 2012-05-03T00:58:49.673 に答える
3

それらを同じように設定すると、予測可能性が高まります。GCがより多くのメモリが必要であると判断したときに同じように設定しないと、スペースを確保するためにオブジェクトを割り当ててシャッフルするのに時間がかかります。これは、GCアクティビティに追加されます。これが発生している間、リクエストは遅くなり、スループットが低下します。2GBのヒープでは、必要になるたびに約400 MBのメモリが割り当てられ、メモリが不要になるたびに100MBが削除されます。ヒープサイズを増やすと、これらの数が増えます。ヒープは値の間で常に変化します。それは、そのメモリを割り当てて保持するだけではありません。

OSが常にあなたのために利用可能なメモリを持っていることを保証することに関する議論#1については、私は議論の余地があると信じています。サーバーのメモリが不足していて、ソフトウェアを実行するためにすでにマシンの上限を設定している場合は、間違ったサーバーで実行しています。必要なハードウェアを入手して、成長の余地を与えてください。あなたのアプリケーションが2GBを使用できると言うなら、個人的には4GB以上の無料のマシンでそれを持っているでしょう。クライアント/ユーザーベースが拡大した場合、新しいユーザーに対応するためにヒープを増やす自由があります。

于 2012-05-03T02:06:05.420 に答える
2

2番目のポイントは非常に有効です。メモリの取得は低速のIO操作です。特に大きな塊。ただし、2GBは大きなブロックです。これを実行しているのはどのようなハードウェアですか?かなりのメモリがある場合は、それは良い考えです。

ただし、コンピュータに実際には多くのメモリがない場合、2GBのブロックを割り当てることは危険で貪欲になる可能性があります。代わりに、オブジェクトプーリングスキームを作成する必要があります。ガベージコレクターはメモリを取得して独自のメモリプールを実行しますが、2 GBの場合、一部のメモリがOSに解放される可能性があります。

プロファイリングを行うと、メモリを無駄にせず、常にメモリを割り当てることで、どれだけの時間を節約できるかに驚くでしょう。ガベージコレクターは、その多くからあなたを保護しますが、2GBのブロックではそれほど多くはありません。

最終的には、可能であれば...少ないメモリの使用を検討する必要があります。実際のパフォーマンスについては、バッファと配列をキャッシュに保持することを検討してください。これはもう少し複雑ですが、膨大な結果を生み出す可能性があります。

幸運を祈ります

于 2012-05-03T02:16:20.213 に答える
1

JVMを起動すると、初期サイズを設定したかどうかに関係なく、最大ヒープサイズが1つの連続したブロックとして取得されます。その使用量は使用法によって異なります。e..ga helloworldの初期サイズが2Gの場合、2Gは使用されません。初期サイズが行うことは、初期サイズに達するまで使用を制限しようとしないことです。(ただし、実際に必要でない場合は、メインメモリは割り当てられません)

イニシャルを設定すると、起動時間を短縮できます。私は初期サイズをJVMがとにかく大きくなるサイズに設定する傾向があります(または起動時間が短い場合は気にしないでください)

実際の影響は、ヒープサイズが小さいと、一時的なオブジェクトが古いスペースに移動する可能性があり、クリーンアップに費用がかかることです。ヒープサイズが大きいと、一時オブジェクトが破棄されてから何度もコピーされ、完全なgcで削除される可能性があります。

于 2012-05-03T05:34:32.710 に答える