11

メモリの調整が必要なこの webapp があります。すでにアプリケーション自体のプロファイリングを行って調整を行っていますが、最もビジーなインスタンスでは JVM 自体が過度に肥大化しているように見えます。(ボリュームの低いインスタンスにはこの問題はありません。) 詳細:

  • プラットホーム:
    • RHEL4 64 ビット ( Linux 2.6.9-78.0.5.ELsmp #1 SMP x86_64)
    • Sun Java 6 ( Java HotSpot(TM) 64-Bit Server VM (build 10.0-b23, mixed mode))
    • -d64でTomcat 6startup.sh
  • 現在、私の webapp には、本番環境で 64 ビットを実行する利点を必要とするコードが含まれています。
  • しばらくすると (1 週間)、JVM の常駐メモリ サイズ (上に表示) が-Xmx 設定のサイズの 3 倍になることがわかりました。
  • 非ヒープ メモリ サイズなどはすべて比較的些細なものであり、ヒープ サイズのわずか 1 桁のパーセンテージです。
  • 64 ビットのビット アドレス空間を必要とするコード セクションは 1 つだけです。

64 ビット JVM の必要性をリファクタリングして-d64スイッチを削除できた場合、JVM の常駐メモリ フットプリントは小さくなりますか? 言い換えると...

-d64このスイッチは Sun JVM 常駐メモリの使用にどのような影響を与えますか?

4

1 に答える 1

18

d64 スイッチを使用すると、JVM が 64 ビット モードになります。技術的には、Solaris/Linux およびほとんどの Unix では、JVM プロセスは LP64 モデルで実行されます。

LP64 モデルは、ポインターが 32 ビット ポインターではなく 64 ビット幅であるという点で、32 ビット モデル (ILP32) とは異なります。JVM の場合、これによりメモリのアドレス指定可能性が向上しますが、オブジェクト参照だけで占有されるサイズが 2 倍になることも意味します。そのため、32 ビットの JVM と 64 ビットの JVM では、特定の時間に同じ数のオブジェクトの膨張が大きくなります。

よく忘れられるもう 1 つのことは、命令自体のサイズです。64 ビット JVM では、命令のサイズがネイティブ マシン レジスタのサイズを占有します。

ただし、 64 ビット環境で圧縮されたオブジェクト ポインターを使用する場合、JVM は、4 GB を超えるヒープ サイズのポインターを可能な限りエンコードおよびデコードします。簡単に言うと、圧縮ポインターを使用する場合、JVM は 32 ビット幅の値を可能な限り使用しようとします。

ヒント: UseCompressedOops フラグをオンにし、-XX:+UseCompressedOopsを使用して膨張の一部を取り除きます。YMMV ですが、圧縮 oops を使用することでメモリの膨張が最大 50% 減少したと報告されています

編集

UseCompressedOops フラグは、Java HotSpot VM のバージョン 14.0 でサポートされており、Java 6 Update 14 以降で使用できます

于 2009-09-18T12:08:08.830 に答える