414

「java -server」と「java -client」の間に実質的な実際の違いはありますか?

Sunのサイトで見つけられるのは漠然としたものだけです

「-サーバーの起動は遅くなりますが、より速く実行されるはずです」。

本当の違いは何ですか?(現在JDK 1.6.0_07を使用しています。)

4

11 に答える 11

388

これは、実際にはHotSpotと、クライアントとサーバーの構成間で異なるデフォルトのオプション値Java HotSpot VMオプション)にリンクされています。

ホワイトペーパー(Java HotSpotパフォーマンスエンジンアーキテクチャ)の第2章から:

JDKには、クライアント側のオファリングとサーバーアプリケーション用に調整されたVMの2種類のVMが含まれています。これらの2つのソリューションは、Java HotSpotランタイム環境のコードベースを共有しますが、クライアントとサーバーの明確に固有のパフォーマンス特性に適した異なるコンパイラーを使用します。これらの違いには、コンパイルのインライン化ポリシーとヒープのデフォルトが含まれます。

サーバーVMとクライアントVMは似ていますが、サーバーVMは、ピーク動作速度を最大化するように特別に調整されています。これは、起動時間が短い、または実行時のメモリフットプリントが小さいよりも、可能な限り最速の動作速度を必要とする、長時間実行されるサーバーアプリケーションを実行することを目的としています。

クライアントVMコンパイラは、クラシックVMと以前のバージョンのJDKで使用されていたジャストインタイム(JIT)コンパイラの両方のアップグレードとして機能します。クライアントVMは、アプリケーションとアプレットの実行時パフォーマンスを向上させます。Java HotSpotクライアントVMは、アプリケーションの起動時間とメモリフットプリントを削減するように特別に調整されているため、クライアント環境に特に適しています。一般に、クライアントシステムはGUIに適しています。

したがって、実際の違いはコンパイラレベルにもあります。

クライアントVMコンパイラは、サーバーVMでコンパイラによって実行されるより複雑な最適化の多くを実行しようとはしませんが、代わりに、コードの一部を分析およびコンパイルするために必要な時間が短縮されます。これは、クライアントVMの起動が速くなり、必要なメモリフットプリントが小さくなることを意味します。

サーバーVMには、C ++コンパイラーの最適化によって実行される同じタイプの最適化の多くと、仮想メソッド呼び出し間の積極的なインライン化など、従来のコンパイラーでは実行できないいくつかの最適化をサポートする高度な適応コンパイラーが含まれています。これは、静的コンパイラよりも競争力があり、パフォーマンスが優れています。適応最適化テクノロジーは、そのアプローチにおいて非常に柔軟性があり、通常、高度な静的分析およびコンパイル技術よりも優れています。

注:jdk6アップデート10のリリース(アップデートリリースノート:1.6.0_10での変更を参照)は起動時間を改善しようとしましたが、ホットスポットオプションとは異なる理由で、はるかに小さいカーネルで異なる方法でパッケージ化されました。


G. Demeckiはコメントの中で、64ビットバージョンのJDKでは、この-clientオプションは何年もの間無視されていると指摘しています。Windowsコマンド
を参照してください:java

-client

JavaHotSpotクライアントVMを選択します。
64ビット対応のJDKは現在、このオプションを無視し、代わりにJava HotspotServerVMを使用します


2022:Holgerは、コメントJavaSE6 /サーバークラスのマシン検出を参照し、次のように追加しています。

32ビットWindowsシステムでのみ、-client無条件に選択されました。
他のシステムは、マシンが「サーバークラス」であるかどうかをチェックしました。これは、少なくとも2つのコアと少なくとも2GiBのメモリがある場合に満たされました。

-serverこれは、ほとんどすべてが今かなり長い間使用されている理由を説明しています。あなたが見つけることができる最も安いコンピュータでさえ、「サーバークラス」のマシンです。Sun / Oracle 64ビルドには、クライアントJVMも付属していませんでした。

于 2008-10-13T18:57:45.393 に答える
91

古いバージョンの 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を使用して、実行中のすべての詳細を確認できることも忘れないでくださいjvisualvmJAVA_OPTSこれは、コマンド ライン オプションを変更するスクリプトを設定または使用するユーザーまたはモジュールがある場合に役立ちます。これにより、ヒープおよびpermgenスペースの使用状況を他の多くの統計とともにリアルタイムで監視することもできます。

于 2012-08-17T10:17:39.723 に答える
33

私が今気付いた違いの1つは、「クライアント」モードでは、JVMが実際に未使用のメモリをオペレーティングシステムに戻すように見えるのに対し、「サーバー」モードでは、JVMがメモリを取得すると、それを与えないことです。戻る。それはとにかくJava6を搭載したSolarisでどのように表示されるかです(prstat -Zプロセスに割り当てられたメモリの量を確認するために使用します)。

于 2010-09-23T06:11:38.417 に答える
24

Oracle のオンライン ドキュメントには、Java SE 7 に関するいくつかの情報が記載されています。

java - Windows の Java アプリケーション起動ページでは、オプション-clientは 64 ビット JDK では無視されます。

Java HotSpot クライアント VM を選択します。現在、64 ビット対応の jdk はこのオプションを無視し、代わりに Java HotSpot Server VM を使用します。

ただし、(物事を面白くするために)その下に次の-serverように記載されています。

Java HotSpot サーバー VM を選択します。64 ビット対応の jdk では、Java HotSpot Server VM のみがサポートされるため、-server オプションは暗黙的です。これは、将来のリリースで変更される可能性があります。

Server-Class Machine Detectionページには、OS とアーキテクチャによって選択された VM に関する情報が表示されます。

これがどれだけJDK 6に当てはまるかはわかりません。

于 2013-03-18T07:15:06.647 に答える
16

Goetz から - Java Concurrency in Practice:

  1. デバッグのヒント: サーバー アプリケーションの場合は、開発やテストの場合でも、JVM を呼び出すときに必ず-serverJVM コマンド ライン スイッチを指定してください。サーバー JVM は、クライアント JVM よりも多くの最適化を実行します。たとえば、ループ内で変更されない変数をループから巻き上げます。開発環境 (クライアント JVM) で動作するように見えるコードが、デプロイメント環境 (サーバー JVM) では機能しなくなる可能性があります。たとえば、リスト 3.4 で変数 sleep を volatile として宣言するのを「忘れた」場合、サーバー JVM はテストをループから引き上げることができます (無限ループに変えます) が、クライアント JVM はそうしません。開発で現れる無限ループは、本番環境でしか現れない無限ループよりもはるかにコストがかかりません。

リスト 3.4. 羊を数える。

volatile boolean asleep;
...
while (!asleep)
   countSomeSheep();

私の強調。YMMV

于 2016-03-10T10:29:43.507 に答える
15

サーバー VM の IIRC は、起動時により多くのホットスポット最適化を行うため、実行速度は速くなりますが、起動に時間がかかり、より多くのメモリを使用します。クライアント VM は、起動を高速化するために、ほとんどの最適化を延期します。

編集して追加:これは Sun からの情報です。あまり具体的ではありませんが、いくつかのアイデアが得られます。

于 2008-10-13T18:48:58.517 に答える
5

IIRC、それにはガベージコレクション戦略が含まれます。理論的には、クライアントとサーバーは存続期間の短いオブジェクトに関して異なるというものです。これは、最新の GC アルゴリズムにとって重要です。

サーバーモードのリンクです。残念ながら、彼らはクライアントモードについて言及していません。

これは、一般的なGCに関する非常に完全なリンクです。これはより基本的な記事です。サーバーとクライアントのどちらに対処するかはわかりませんが、これは関連資料です。

No Fluff Just Stuff では、Ken Sipe と Glenn Vandenburg がこの種のことについて素晴らしい話をしています。

于 2008-10-13T18:57:26.533 に答える
3

2つの起動時間の違いには気づきませんでしたが、「-server」(Solarisサーバー、SunRaysを使用してアプリを実行するすべての人)を使用すると、アプリケーションのパフォーマンスが最小限に向上しました。それは1.5未満でした。

于 2008-10-13T18:45:07.493 に答える
1

前回これを見たとき (確かに少し前のことですが)、私が気づいた最大の違いはガベージ コレクションでした。

ちゃんと覚えたら:

  • サーバー ヒープ VM は、クライアント VM とは世代数が異なり、ガベージ コレクション アルゴリズムも異なります。これはもう真実ではないかもしれません
  • サーバー VM はメモリを割り当て、OS に解放しません。
  • サーバー VM はより高度な最適化アルゴリズムを使用するため、最適化に必要な時間とメモリが大きくなります。

jvisualvmツールを使用して 2 つの Java VM、1 つのクライアント、1 つのサーバーを比較すると、ガベージ コレクションの頻度と効果、および世代数に違いがあることがわかります。

違いがよくわかるスクリーンショットが 2 枚ありましたが、サーバー VM のみを実装する 64 ビット JVM を使用しているため、再現できません。(そして、私のシステムでも 32 ビット バージョンをダウンロードして苦労することはできません。)

サーバー VM とクライアント VM の両方で Windows でいくつかのコードを実行しようとしたところ、両方で同じ世代モデルが得られたようです...

于 2013-03-22T14:53:23.163 に答える