0

皆さん、先週、大規模な顧客サイトでの Java サーバー アプリケーションの負荷テスト ワークショップ中に、64 ビット JVM を使用すると、約 1300 ~ 1800 の同時セッションしか実行できませんでしたが、同じ構成では 2800 の同時セッションを実行できました。 32 ビット JVM で。

環境情報: Solaris 10 、Java 1.6.0_30 、Jetty 8.1.5 、Web アプリケーションは I/O バウンドであり、プロセスごとに 1000 のほとんどアイドル状態のスレッドがあり、6 ~ 12 の Java プロセスがほとんど違いなく生成されました。障害発生時、CPU 容量は 50% 未満、ファイル記述子は 65536 に設定されていました。

ある時点で 64 ビット JVM を実行すると、CPU が 50% 未満の状態になり、マシン レベルと Java プロセス レベルの両方で十分なメモリがまだ利用可能でした。この時点で、製品のさまざまなレイヤーで「IOException」と「EOFException」が発生し始めました。私たちが知る限り、この時点で実際のネットワークや通信の問題はありませんでした. Solaris マシンでソケット通信に関連するリソースが不足しているように見えます。64 ビット JVM は、32 ビット JVM と比較してこのリソースを 2 倍消費しているようです。

何か案は ?注目すべき違いの 1 つは、64 ビット JVM はスレッド スタックごとに 1024k を消費するのに対し、32 ビットはスレッドごとに 512k しか消費しないことです。これが理由でしょうか?スレッド スタックとソケット I/O は、Solaris で同じメモリ プールから割り当てられますか? このプールを増やすことはできますか? 64 ビット VM のスレッド スタック サイズを 512k に減らす必要がありますか?

4

3 に答える 3

0

私の結論は、私たちが遭遇する制限は次のとおりです: (1) サーバープロセスは、サーバーマシンの物理メモリーのサイズを超えてメモリ割り当ての合計を増やします --> (2) Solaris サーバーはメモリページをディスクにスワップし始めます - →(3)スワッピングのせいで、Javaのガベージコレクションが非常に遅くなる(スワッピングがひどすぎて、1回の収集で300秒以上かかることもある!) -->(4)ソケット通信を使用している場合、一部のプロセスが待機している他のプロセスがガベージ コレクションでスタックしている間の I/O の場合 --> (5) GC を実行するプロセスが他のプロセスからの要求に応答しないため、予期しない場所でソケット タイムアウトと EOF 例外が発生します。(6) 技術的には、Solaris のスワップ ファイルにはまだ使用可能なメモリがあり、Java の最大ヒープ サイズを超えていないため、OutOfMemory エラーは発生しません。

したがって、私の結論は次のとおりです。(1) 32 ビット JVM が 64 ビット JVM よりも優れている理由は、64 ビットが 32 ビットと比較して 50% 以上のメモリを必要とするためです。 32ビットのものと比較して負荷がかかります。(2) 特定の Solaris サーバーで 4000 の同時セッションを実行するための鍵は、メモリ消費を削減するか、利用可能な物理メモリを増やすことです。(3) より適切にスケーリングするには、32 ビット JVM でより多くのスレッドを生成できるようにする必要があります。デフォルトでは、プロセスごとに 3000 スレッドしか生成または生成できず、これは私の特定のユース ケースには十分ではありません。

構成の変更: (1) 次のコマンド ライン フラグを追加して、ガベージ コレクションを監視します -XX:+PrintGCDetails -XX:+PrintGCTimeStamps (2) スレッド スタック サイズを -Xss384k に減らします。これにより、プロセスごとにより多くのスレッドを実行できるようになり、メモリ割り当てが削減されます。プロセスの。Solaris のデフォルトのスタック サイズは、32 ビットでは 512k、64 ビットでは 1024k です。(3) prstat コマンドと vmstat コマンドを使用して負荷テスト中のメモリ消費を監視し、過剰なスワッピングがないことを確認します。(4) メモリを節約し、ガベージ コレクションを高速化するために、32 ビット Java プロセスごとに -mx800m を超える割り当てを行わないでください。必要に応じてより多くのプロセスを生成しますが、物理メモリがいっぱいにならないようにしてください。

于 2013-09-24T08:25:19.857 に答える
0

-XX:+UseCompressedOopsオプション (通常のオブジェクト ポインターを圧縮する) を JVM に追加して、テストがどのように比較されるかを確認することをお勧めします。

このオプションは、使用する JVM バージョンではまだデフォルトではない可能性があり、64 ビット仮想メモリ空​​間全体の利点を維持しながら、64 ビット ポインタ サイズの悪影響を補います。

于 2013-09-01T09:10:12.600 に答える