回答:
これは実際にはHotSpotとリンクされており、デフォルトのオプション値(Java HotSpot VM Options)はクライアントとサーバーの設定で異なります。
第2章ホワイトペーパー(のは、Java HotSpotパフォーマンスエンジンアーキテクチャ):
JDKには、クライアント側のオファリングとサーバーアプリケーション用に調整されたVMの2種類のVMが含まれています。これら2つのソリューションは、Java HotSpotランタイム環境のコードベースを共有しますが、クライアントとサーバーの明確に固有のパフォーマンス特性に適した異なるコンパイラーを使用します。これらの違いには、コンパイルのインラインポリシーとヒープのデフォルトが含まれます。
サーバーVMとクライアントVMは似ていますが、サーバーVMはピーク動作速度を最大化するように特別に調整されています。これは、高速な起動時間や実行時のメモリフットプリントよりも高速で可能な最高速の動作速度を必要とする、長時間実行されるサーバーアプリケーションを実行するためのものです。
クライアントVMコンパイラは、クラシックVMと、以前のバージョンのJDKで使用されていたジャストインタイム(JIT)コンパイラの両方のアップグレードとして機能します。クライアントVMは、アプリケーションとアプレットの実行時パフォーマンスを向上させます。Java HotSpot Client VMは、アプリケーションの起動時間とメモリフットプリントを削減するように特別に調整されており、クライアント環境に特に適しています。一般に、クライアントシステムはGUIに適しています。
したがって、実際の違いはコンパイラレベルにもあります。
クライアントVMコンパイラは、サーバーVMのコンパイラによって実行されるより複雑な最適化の多くを実行しようとはしませんが、その代わりに、コードの一部を分析してコンパイルするために必要な時間を短縮できます。つまり、クライアントVMはより速く起動でき、必要なメモリフットプリントが小さくなります。
サーバーVMには、C ++コンパイラの最適化によって実行される同じタイプの最適化の多くをサポートする高度な適応型コンパイラと、仮想メソッド呼び出し全体の積極的なインライン化など、従来のコンパイラでは実行できないいくつかの最適化が含まれています。これは、静的コンパイラよりも競争力があり、パフォーマンスが優れている点です。適応最適化テクノロジーは、そのアプローチが非常に柔軟であり、通常、高度な静的分析およびコンパイル技術よりも優れています。
注:jdk6 update 10のリリース(アップデートリリースノート:1.6.0_10での変更を参照)は起動時間を改善しようとしましたが、ホットスポットオプションとは異なる理由で、はるかに小さいカーネルで異なる方法でパッケージ化されました。
G. Demecki は、コメントで指摘しているように、64ビットバージョンのJDKでは、この-client
オプションは長年にわたって無視されます。Windows コマンドを
参照してください:java
-client
Java HotSpot Client VMを選択します。
64ビット対応のJDKは現在このオプションを無視し、代わりにJava Hotspot Server VMを使用しています。
-client
オプションは何年もの間無視されます。
古いバージョンのJavaで最も目に見える直接的な違いは-client
、-server
アプリケーションではなくに割り当てられるメモリです。たとえば、私のLinuxシステムでは、次のようになります。
$ java -XX:+PrintFlagsFinal -version 2>&1 | grep -i -E 'heapsize|permsize|version'
uintx AdaptivePermSizeWeight = 20 {product}
uintx ErgoHeapSizeLimit = 0 {product}
uintx InitialHeapSize := 66328448 {product}
uintx LargePageHeapSizeThreshold = 134217728 {product}
uintx MaxHeapSize := 1063256064 {product}
uintx MaxPermSize = 67108864 {pd product}
uintx PermSize = 16777216 {pd product}
java version "1.6.0_24"
デフォルトは-server
ですが、次の-client
オプションがあります。
$ java -client -XX:+PrintFlagsFinal -version 2>&1 | grep -i -E 'heapsize|permsize|version'
uintx AdaptivePermSizeWeight = 20 {product}
uintx ErgoHeapSizeLimit = 0 {product}
uintx InitialHeapSize := 16777216 {product}
uintx LargePageHeapSizeThreshold = 134217728 {product}
uintx MaxHeapSize := 268435456 {product}
uintx MaxPermSize = 67108864 {pd product}
uintx PermSize = 12582912 {pd product}
java version "1.6.0_24"
そのため、-server
このjava
バージョンでは、ほとんどのメモリ制限と初期割り当てがはるかに高くなっています。
ただし、これらの値は、アーキテクチャ、オペレーティングシステム、jvmバージョンのさまざまな組み合わせによって変わる可能性があります。jvmの最近のバージョンでは、フラグが削除され、サーバーとクライアントの違いの多くが削除されました。
をjvm
使用して実行中のすべての詳細を確認できることも覚えておいてくださいjvisualvm
。これは、JAVA_OPTS
コマンドラインオプションを変更するスクリプトを設定または使用するユーザーまたはモジュールがある場合に便利です。これにより、ヒープとpermgenのスペース使用量を、他の多くの統計とともにリアルタイムで監視することもできます。
-clientシステムと-serverシステムは異なるバイナリです。これらは基本的に、同じランタイムシステムに接続する2つの異なるコンパイラ(JIT)です。クライアントシステムは、起動時間が短いかフットプリントが小さいアプリケーションに最適です。サーバーシステムは、全体的なパフォーマンスが最も重要なアプリケーションに最適です。一般に、クライアントシステムはGUIなどのインタラクティブアプリケーションに適しています。
両方のスイッチで次のコードを実行します。
package com.blogspot.sdoulger;
public class LoopTest {
public LoopTest() {
super();
}
public static void main(String[] args) {
long start = System.currentTimeMillis();
spendTime();
long end = System.currentTimeMillis();
System.out.println("Time spent: "+ (end-start));
LoopTest loopTest = new LoopTest();
}
private static void spendTime() {
for (int i =500000000;i>0;i--) {
}
}
}
注:コードは一度だけコンパイルされます!クラスは両方の実行で同じです!
-client:
java.exe -client -classpath C:\ mywork \ classes com.blogspot.sdoulger.LoopTest使用
:766
-serverの場合:
java.exe -server -classpath C:\ mywork \ classes com.blogspot.sdoulger.LoopTest
費やした時間:0
サーバーシステムをより積極的に最適化する場合は、何も実行しないことがわかっているため、ループを削除してください。
Oracleのオンラインドキュメントには、Java SE 7に関する情報が記載されています。
上のjava - Javaアプリケーション起動用のWindows用のページ、-client
オプションが64ビットJDKでは無視されます。
Java HotSpot Client VMを選択します。64ビット対応のjdkは現在このオプションを無視し、代わりにJava HotSpot Server VMを使用しています。
ただし、(物事を面白くするために)その下-server
では、
Java HotSpot Server VMを選択します。64ビット対応のjdkでは、Java HotSpot Server VMのみがサポートされているため、-serverオプションは暗黙的です。これは将来のリリースで変更される可能性があります。
サーバークラスマシンの検出のページは、VMがOSやアーキテクチャによって選択されている情報を提供します。
これがJDK 6にどの程度当てはまるのかわかりません。
Goetzから-実際のJava同時実行性:
- デバッグのヒント:サーバーアプリケーションの
-server
場合、開発やテストであっても、JVMを呼び出すときは常にJVMコマンドラインスイッチを指定してください。サーバーJVMは、クライアントJVMよりも多くの最適化を実行します。たとえば、ループ内で変更されない変数をループから引き上げます。開発環境(クライアントJVM)で動作するように見えるコードは、デプロイメント環境(サーバーJVM)で機能しなくなる可能性があります。たとえば、リスト3.4で変数asleepをvolatileとして宣言することを「忘れた」場合、サーバーJVMはテストをループから引き上げ(無限ループに変換)できましたが、クライアントJVMはそうしませんでした。開発で現れる無限ループは、本番でのみ現れるループよりもはるかに低コストです。リスト3.4 羊を数える。
volatile boolean asleep; ... while (!asleep) countSomeSheep();
私の強調。YMMV
2つの起動時間の違いに気づきませんでしたが、 "-server"(Solarisサーバー、アプリを実行するためにSunRaysを使用しているすべてのユーザー)を使用して、アプリケーションのパフォーマンスの改善を最小限に抑えました。それは1.5未満でした。
前回これを見たとき(確かにしばらく前だったと思います)、気づいた最大の違いはガベージコレクションにありました。
ちゃんと覚えたら:
jvisualvmツールを使用して、2つのJava VM、1つのクライアント、1つのサーバーを比較できる場合は、ガベージコレクションの頻度と効果、および世代数に違いがあるはずです。
違いを非常によく示すスクリーンショットのペアがありましたが、サーバーVMのみを実装する64ビットJVMがあるため、再現できません。(そして、私も自分のシステムに32ビット版をダウンロードして悩ませることはできません。)
これはもう当てはまらないようで、サーバーとクライアントの両方のVMを使用してWindowsでいくつかのコードを実行しようとすると、両方に同じ生成モデルが表示されるようです...
バージョン1.4から1.7( "1.7.0_55")への移行を行う場合、ここで確認したことは、クライアントおよびサーバーモードでheapsize | permsize | ThreadStackSizeパラメーターに割り当てられたデフォルト値にそのような違いはありません。
ちなみに(http://www.oracle.com/technetwork/java/ergo5-140223.html)。これは、上記のリンクから抜粋したスニペットです。
initial heap size of 1/64 of physical memory up to 1Gbyte
maximum heap size of ¼ of physical memory up to 1Gbyte
ThreadStackSizeは1.7で高くなっていますが、Open JDKフォーラムを通過しているときに、フレームサイズが1.7バージョンでいくらか高くなっているという議論があります。実際の違いは、アプリケーションの動作に基づいて実行時に測定できる可能性があると考えられています