Wirkliche Unterschiede zwischen "Java-Server" und "Java-Client"?

394

Gibt es einen wirklichen praktischen Unterschied zwischen "Java-Server" und "Java-Client"?

Alles, was ich auf Suns Website finden kann, ist vage

"-server startet langsamer, sollte aber schneller laufen".

Was sind die wirklichen Unterschiede? (Derzeit wird JDK 1.6.0_07 verwendet.)

Paul Tomblin
quelle

Antworten:

368

Das ist wirklich verknüpft HotSpot und die Standardoptionswerte ( Java HotSpot VM - Optionen ) , die zwischen Client und Server - Konfiguration abweichen.

Aus Kapitel 2 des Whitepapers ( Die Java HotSpot Performance Engine-Architektur ):

Das JDK enthält zwei Varianten der VM: ein clientseitiges Angebot und eine für Serveranwendungen optimierte VM. Diese beiden Lösungen teilen sich die Codebasis der Java HotSpot-Laufzeitumgebung, verwenden jedoch unterschiedliche Compiler, die für die eindeutig einzigartigen Leistungsmerkmale von Clients und Servern geeignet sind. Diese Unterschiede umfassen die Kompilierungs-Inlining-Richtlinie und die Heap-Standardeinstellungen.

Obwohl die Server- und Client-VMs ähnlich sind, wurde die Server-VM speziell optimiert, um die maximale Betriebsgeschwindigkeit zu maximieren. Es ist für die Ausführung von Serveranwendungen mit langer Laufzeit vorgesehen, die die schnellstmögliche Betriebsgeschwindigkeit mehr als eine schnelle Startzeit oder einen geringeren Speicherbedarf zur Laufzeit benötigen.

Der Client-VM-Compiler dient als Upgrade sowohl für die Classic-VM als auch für die Just-in-Time-Compiler (JIT), die von früheren Versionen des JDK verwendet wurden. Die Client-VM bietet eine verbesserte Laufzeitleistung für Anwendungen und Applets. Die Java HotSpot Client-VM wurde speziell optimiert, um die Startzeit der Anwendung und den Speicherbedarf zu verringern, sodass sie sich besonders gut für Clientumgebungen eignet. Im Allgemeinen ist das Client-System für GUIs besser.

Der eigentliche Unterschied liegt also auch auf der Compilerebene:

Der Client-VM-Compiler versucht nicht, viele der komplexeren Optimierungen auszuführen, die vom Compiler in der Server-VM durchgeführt werden. Im Gegenzug benötigt er jedoch weniger Zeit, um einen Code zu analysieren und zu kompilieren. Dies bedeutet, dass die Client-VM schneller gestartet werden kann und einen geringeren Speicherbedarf benötigt.

Die Server-VM enthält einen erweiterten adaptiven Compiler, der viele der gleichen Arten von Optimierungen unterstützt, die durch die Optimierung von C ++ - Compilern durchgeführt werden, sowie einige Optimierungen, die von herkömmlichen Compilern nicht durchgeführt werden können, z. B. aggressives Inlining über Aufrufe virtueller Methoden hinweg. Dies ist ein Wettbewerbs- und Leistungsvorteil gegenüber statischen Compilern. Die adaptive Optimierungstechnologie ist in ihrem Ansatz sehr flexibel und übertrifft in der Regel sogar fortgeschrittene statische Analyse- und Kompilierungstechniken.

Hinweis: Mit der Veröffentlichung von jdk6 Update 10 (siehe Versionshinweise zum Update : Änderungen in 1.6.0_10 ) wurde versucht, die Startzeit zu verbessern, jedoch aus einem anderen Grund als den Hotspot-Optionen, da sie mit einem viel kleineren Kernel anders gepackt wurden .


G. Demecki weist in den Kommentaren darauf hin, dass in 64-Bit-Versionen von JDK die -clientOption für viele Jahre ignoriert wird.
Siehe Windows- javaBefehl :

-client

Wählt die Java HotSpot Client-VM aus.
Ein 64-Bit-fähiges JDK ignoriert diese Option derzeit und verwendet stattdessen die Java Hotspot Server-VM .

VonC
quelle
7
jdk6 Update 10 und höher verfügen über einen Hintergrundprozess, der die Laufzeitbibliotheken im Speicher hält und einen viel schnelleren Start für neue Prozesse ermöglicht, als alles bei Bedarf einblättern zu müssen.
Thorbjørn Ravn Andersen
1
Dachte, der Client vm hat auch aggressiv inliniert, na ja.
Thorbjørn Ravn Andersen
1
Ich denke, diese Antwort sollte aktualisiert werden. Da in den 64-Bit-Versionen von JDK die -clientOption viele Jahre lang ignoriert wird.
G. Demecki
@ G.Demecki Sicher: Haben Sie einen Link, der dokumentiert, dass diese Option veraltet ist oder ignoriert wird?
VonC
1
Sicher. Hier finden Sie einige Dokumentationen für Java 7 für Windows. Und überraschenderweise finden Sie ähnliche Informationen auch in der Java 6- Dokumentation .
G. Demecki
90

Der sichtbarste unmittelbare Unterschied in älteren Java-Versionen wäre der Speicher, der einer -clientim Gegensatz zu einer -serverAnwendung zugewiesen wird . Zum Beispiel bekomme ich auf meinem Linux-System:

$ 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"

wie es standardmäßig ist -server, aber mit der -clientOption bekomme ich:

$ 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"

Daher sind die -servermeisten Speicherbeschränkungen und anfänglichen Zuordnungen für diese javaVersion viel höher .

Diese Werte können sich jedoch für verschiedene Kombinationen von Architektur, Betriebssystem und JVM-Version ändern. Neuere Versionen des JVM haben Flags entfernt und viele der Unterschiede zwischen Server und Client entfernt.

Denken Sie auch daran, dass Sie alle Details eines Laufens jvmmit sehen können jvisualvm. Dies ist nützlich, wenn Sie Benutzer oder Module haben, die JAVA_OPTSSkripts festlegen oder verwenden, die Befehlszeilenoptionen ändern. So können Sie auch in Echtzeit überwachen Heap und PermGen Raumnutzung zusammen mit vielen anderen Statistiken.

Mark Booth
quelle
2
Es gibt mir die gleichen Nummern im Server-Server- und -client-Modus für die Java-Version "1.7.0_79" unter CentOS 7 [Java (TM) SE-Laufzeitumgebung (Build 1.7.0_79-b15) Java HotSpot (TM) 64-Bit-Server-VM ]
Basil Musa
4
Deshalb habe ich die Antwort gegeben. Es geht nicht um die Werte, es geht darum, dass jeder jederzeit die Antwort für seine spezifische JVM-Version finden kann.
Mark Booth
33

Die Systeme -client und -server sind unterschiedliche Binärdateien. Es handelt sich im Wesentlichen um zwei verschiedene Compiler (JITs), die an dasselbe Laufzeitsystem angeschlossen sind. Das Client-System ist optimal für Anwendungen, die schnelle Startzeiten oder geringe Stellflächen benötigen. Das Serversystem ist optimal für Anwendungen, bei denen die Gesamtleistung am wichtigsten ist. Im Allgemeinen eignet sich das Client-System besser für interaktive Anwendungen wie GUIs

Geben Sie hier die Bildbeschreibung ein

Wir führen den folgenden Code mit beiden Schaltern aus:

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--) {
        }
    }
}

Hinweis: Der Code wurde nur einmal kompiliert! Die Klassen sind in beiden Läufen gleich!

Mit -client:
java.exe -client -classpath C: \ mywork \ classes com.blogspot.sdoulger.LoopTest
Zeitaufwand: 766

Mit -server:
java.exe -server -classpath C: \ mywork \ classes com.blogspot.sdoulger.LoopTest
Zeitaufwand: 0

Es scheint, dass die aggressivere Optimierung des Serversystems die Schleife entfernt, da es versteht, dass es keine Aktion ausführt!

Referenz

Premraj
quelle
33

Ein Unterschied, den ich gerade bemerkt habe, ist, dass die JVM im "Client" -Modus anscheinend tatsächlich nicht verwendeten Speicher an das Betriebssystem zurückgibt, während im "Server" -Modus die JVM den Speicher nicht mehr bereitstellt, sobald sie den Speicher erfasst zurück. So wird es unter Solaris mit Java6 ohnehin angezeigt ( prstat -Zum die einem Prozess zugewiesene Speichermenge anzuzeigen ).

prule
quelle
22

Die Online-Dokumentation von Oracle enthält einige Informationen zu Java SE 7.

Auf Java - der Java Application Launcher- Seite für Windows - wird die -clientOption in einem 64-Bit-JDK ignoriert:

Wählen Sie die Java HotSpot Client-VM aus. Ein 64-Bit-fähiger JDK ignoriert diese Option derzeit und verwendet stattdessen die Java HotSpot Server-VM.

Allerdings (um die Dinge interessant zu machen) heißt es darunter -server:

Wählen Sie die Java HotSpot Server-VM aus. Auf einem 64-Bit-fähigen JDK wird nur die Java HotSpot Server-VM unterstützt, sodass die Option -server implizit ist. Dies kann sich in einer zukünftigen Version ändern.

Auf der Seite Maschinenerkennung der Serverklasse finden Sie Informationen darüber, welche VM vom Betriebssystem und der Architektur ausgewählt wird.

Ich weiß nicht, wie viel davon für JDK 6 gilt.

Pharsikel
quelle
2
Danke, ich habe mich gefragt, warum ich keinen Client / jvm.dll auf JDK7
Archimedes Trajano
16

Von Goetz - Java Parallelität in der Praxis:

  1. Debugging-Tipp: Geben Sie bei Serveranwendungen -serverbeim Aufrufen der JVM immer den JVM-Befehlszeilenschalter an, auch für die Entwicklung und das Testen . Die Server-JVM führt mehr Optimierungen durch als die Client-JVM, z. B. das Hochheben von Variablen aus einer Schleife, die in der Schleife nicht geändert werden. Code, der möglicherweise in der Entwicklungsumgebung (Client-JVM) funktioniert, kann in der Bereitstellungsumgebung (Server-JVM) beschädigt werden. Hätten wir beispielsweise in Listing 3.4 „vergessen“, die schlafende Variable als flüchtig zu deklarieren, könnte die Server-JVM den Test aus der Schleife heben (in eine Endlosschleife verwandeln), die Client-JVM jedoch nicht . Eine Endlosschleife, die sich in der Entwicklung zeigt, ist weitaus kostengünstiger als eine, die sich nur in der Produktion zeigt.

Listing 3.4. Schafe zählen.

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

Mein Schwerpunkt. YMMV

Adam
quelle
15

IIRC Die Server-VM führt beim Start mehr Hotspot-Optimierungen durch, sodass sie schneller ausgeführt wird, der Start jedoch etwas länger dauert und mehr Speicher benötigt. Die Client-VM verschiebt den größten Teil der Optimierung, um einen schnelleren Start zu ermöglichen.

Bearbeiten, um hinzuzufügen: Hier sind einige Informationen von Sun, die nicht sehr spezifisch sind, aber Ihnen einige Ideen geben.

Mike Akers
quelle
5

IIRC beinhaltet Garbage Collection-Strategien. Die Theorie besagt, dass sich Client und Server in Bezug auf kurzlebige Objekte unterscheiden, was für moderne GC-Algorithmen wichtig ist.

Hier ist ein Link zum Servermodus. Leider erwähnen sie den Client-Modus nicht.

Hier ist ein sehr gründlicher Link zu GC im Allgemeinen. Dies ist ein grundlegenderer Artikel . Ich bin mir nicht sicher, ob einer der Adressen -server oder -client ist, aber dies ist relevantes Material.

Bei No Fluff Just Stuff führen sowohl Ken Sipe als auch Glenn Vandenburg großartige Gespräche über solche Dinge.

Michael Ostern
quelle
3

Ich habe keinen Unterschied in der Startzeit zwischen den beiden bemerkt, aber mit "-server" (Solaris-Server, jeder, der SunRays zum Ausführen der App verwendet) eine sehr minimale Verbesserung der Anwendungsleistung festgestellt. Das war unter 1,5.

Brian Knoblauch
quelle
6
Kommt darauf an, was dein Programm macht. Bei einigen prozessorintensiven Anwendungen, die wiederholt dasselbe tun, habe ich mit -server enorme (bis zu 10-fache) Verbesserungen festgestellt.
Dan Dyer
1
Dan, hast du einen Hinweis darauf? Ich würde gerne weiter nachforschen.
Thorbjørn Ravn Andersen
1
Das Ausführen von Sunflow mit der Server-VM ist VIEL schneller als der Client. sunflow.sourceforge.net
John
1

Das letzte Mal, als ich mir das anschaute (und zugegebenermaßen war es eine Weile her), war der größte Unterschied, den ich bemerkte, die Müllabfuhr.

IIRC:

  • Die Server-Heap-VM hat eine andere Anzahl von Generationen als die Client-VM und einen anderen Garbage Collection-Algorithmus. Dies kann nicht mehr wahr sein
  • Die Server-VM weist Speicher zu und gibt ihn nicht an das Betriebssystem frei
  • Die Server-VM verwendet komplexere Optimierungsalgorithmen und hat daher einen höheren Zeit- und Speicherbedarf für die Optimierung

Wenn Sie zwei Java-VMs, einen Client und einen Server mit dem Tool jvisualvm vergleichen können , sollten Sie einen Unterschied in der Häufigkeit und Wirkung der Speicherbereinigung sowie in der Anzahl der Generationen feststellen .

Ich hatte ein paar Screenshots, die den Unterschied wirklich gut zeigten, aber ich kann nicht reproduzieren, da ich eine 64-Bit-JVM habe, die nur die Server-VM implementiert. (Und ich kann mir nicht die Mühe machen, die 32-Bit-Version auch auf meinem System herunterzuladen und zu diskutieren.)

Dies scheint nicht mehr der Fall zu sein. Nachdem ich versucht habe, Code unter Windows sowohl mit Server- als auch mit Client-VMs auszuführen, erhalte ich anscheinend für beide das gleiche Generationsmodell ...

brice
quelle
1

Bei einer Migration von Version 1.4 auf Version 1.7 ("1.7.0_55"). Wir haben hier festgestellt, dass es keine derartigen Unterschiede bei den Standardwerten gibt, die den Parametern heapsize | permsize | ThreadStackSize im Client- und Servermodus zugewiesen werden.

Übrigens ( http://www.oracle.com/technetwork/java/ergo5-140223.html) ). Dies ist der Ausschnitt aus dem obigen Link.

initial heap size of 1/64 of physical memory up to 1Gbyte
maximum heap size of ¼ of physical memory up to 1Gbyte

ThreadStackSize ist in 1.7 höher, während im Open JDK-Forum diskutiert wird, dass die Frame-Größe in Version 1.7 etwas höher ist. Es wird angenommen, dass ein realer Unterschied zur Laufzeit basierend auf Ihrem Verhalten Ihrer Anwendung gemessen werden kann

Nuwan Arambage
quelle