Les véritables différences entre "java server" et "java -client"?


Y a-t-il une réelle différence pratique entre "java-server" et "java-client"? Tout ce que je peux trouver sur le site de Sun est un vague "-le serveur démarre plus lentement mais devrait fonctionner plus vite". Quelles sont les vraies différences? (En utilisant JDK 1.6.0_07 actuellement.)

Author: Alexander Bird, 2008-10-13

11 answers

Ceci est vraiment lié à HotSpot et aux valeurs d'option par défaut (Java HotSpot VM Options ) qui diffèrent entre la configuration du client et du serveur.

De Chapitre 2 du livre blanc (L'architecture Java HotSpot Performance Engine):

Le JDK comprend deux versions de la VM-une offre côté client et une VM adaptée aux applications serveur. Ces deux solutions partagent le code de l'environnement d'exécution Java HotSpot base, mais utiliser différents compilateurs qui sont adaptés aux caractéristiques de performance distinctement uniques des clients et des serveurs. Ces différences incluent la stratégie d'inlining de compilation et les valeurs par défaut de tas.

Bien que les machines virtuelles du serveur et du client soient similaires, la machine virtuelle du serveur a été spécialement réglée pour maximiser la vitesse de fonctionnement maximale. Il est destiné à l'exécution d'applications serveur de longue durée, qui nécessitent la vitesse de fonctionnement la plus rapide possible plus qu'un temps de démarrage rapide ou plus petit de la mémoire d'exécution de l'empreinte.

Le compilateur de machine virtuelle Client sert de mise à niveau à la fois pour la machine virtuelle classique et pour les compilateurs juste à temps (JIT) utilisés par les versions précédentes du JDK. La machine virtuelle cliente offre des performances d'exécution améliorées pour les applications et les applets. La machine virtuelle Java HotSpot Client a été spécialement conçue pour réduire le temps de démarrage des applications et l'empreinte mémoire, ce qui la rend particulièrement bien adaptée aux environnements clients. En général, le système client est meilleur pour les interfaces graphiques.

Donc la vraie différence est aussi au niveau du compilateur:

Le compilateur de la machine virtuelle client n'essaie pas d'exécuter la plupart des optimisations les plus complexes effectuées par le compilateur dans la machine virtuelle serveur, mais en échange, il faut moins de temps pour analyser et compiler un morceau de code. Cela signifie que la machine virtuelle cliente peut démarrer plus rapidement et nécessite une empreinte mémoire plus petite.

La machine virtuelle du serveur contient un compilateur adaptatif avancé qui prend en charge plusieurs des mêmes types de optimisations effectuées en optimisant les compilateurs C++, ainsi que certaines optimisations qui ne peuvent pas être effectuées par les compilateurs traditionnels, telles que l'inlining agressif à travers les invocations de méthodes virtuelles. C'est un avantage concurrentiel et de performance par rapport aux compilateurs statiques. La technologie d'optimisation adaptative est très flexible dans son approche et surpasse généralement même les techniques avancées d'analyse et de compilation statiques.

Remarque: La sortie de jdk6 update 10 (voir Update Notes de version: Les changements dans 1.6.0_10 ) ont essayé d'améliorer le temps de démarrage, mais pour une raison différente de celle des options hotspot, étant empaqueté différemment avec un noyau beaucoup plus petit.


G. Demecki soulignedans les commentaires que dans les versions 64 bits de JDK, l'option -client est ignorée pendant de nombreuses années.
Voir Windows java commande:

-client

Sélectionne la machine virtuelle Java HotSpot Client.
Un JDK compatible 64 bits ignore actuellement cela option et utilise à la place la machine virtuelle Java Hotspot Server .

 333
Author: VonC, 2017-05-23 12:02:46

La différence immédiate la plus visible dans les anciennes versions de Java serait la mémoire allouée à une -client par opposition à une application -server. Par exemple, sur mon système Linux, j'obtiens:

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

Comme il est par défaut -server, mais avec l'option -client j'obtiens:

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

Donc avec -server la plupart des limites de mémoire et des allocations initiales sont beaucoup plus élevées pour cette version java.

Ces valeurs peuvent changer pour différentes combinaisons d'architecture, de système d'exploitation et de jvm version cependant. Les versions récentes de la jvm ont supprimé les drapeaux et déplacé de nombreuses distinctions entre le serveur et le client.

Rappelez-vous aussi que vous pouvez voir tous les détails de l'exécution d'un jvm utiliser jvisualvm. Ceci est utile si vous avez des utilisateurs qui ou des modules qui définissent JAVA_OPTS ou utilisent des scripts qui modifient les options de la ligne de commande. Cela vous permettra aussi de suivre, en temps réel, tas et permgen l'utilisation de l'espace ainsi que beaucoup d'autres stats.

 82
Author: Mark Booth, 2016-01-11 14:34:32

Une différence que je viens de remarquer est qu'en mode "client", il semble que la JVM redonne de la mémoire inutilisée au système d'exploitation - alors qu'en mode "serveur", une fois que la JVM saisit la mémoire, elle ne la restituera pas. C'est comme ça qu'il apparaît sur Solaris avec Java6 de toute façon (en utilisant prstat-Z pour voir la quantité de mémoire allouée à un processus).

 30
Author: prule, 2010-09-23 06:11:38

Les systèmes-client et-serveur sont des binaires différents. Il s'agit essentiellement de deux compilateurs différents (JITs) s'interfaçant avec le même système d'exécution. Le système client est optimal pour les applications nécessitant des temps de démarrage rapides ou de petites empreintes, le système serveur est optimal pour les applications où les performances globales sont les plus importantes. En général, le système client est mieux adapté aux applications interactives telles que les interfaces graphiques

entrez la description de l'image ici

Nous exécutons ce qui suit code avec les deux commutateurs:

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

Remarque: Le code n'a été compilé qu'une seule fois! Les classes sont les mêmes dans les deux courses!

Avec -client:
Java.exe-client-classpath C:\mywork\classes com.blogspot.sdoulger.LoopTest
Temps passé: 766

Avec -serveur:
Java.exe-serveur-classpath C:\mywork\classes com.blogspot.sdoulger.LoopTest
Temps passé: 0

Il semble que l'optimazation plus agressive du serveur système, retirez la boucle car elle comprend qu'elle n'effectue aucune action!

Référence

 23
Author: Premraj, 2015-08-07 16:14:58

La documentation en ligne d'Oracle fournit des informations pour Java SE 7.

Sur la page java-le lanceur d'applications Java pour Windows, l'option -client est ignorée dans un JDK 64 bits:

Sélectionnez la machine virtuelle Java HotSpot Client. Un jdk compatible 64 bits ignore actuellement cette option et utilise à la place la machine virtuelle Java HotSpot Server.

Cependant (pour rendre les choses intéressantes), sous {[1] } il indique:

Sélectionnez la machine virtuelle Java HotSpot Server. Sur un jdk compatible 64 bits seule la machine virtuelle Java HotSpot Server est prise en charge, donc l'option-server est implicite. Ceci est sujet à changement dans une version future.

La page Server-Class Machine Detection donne des informations sur la machine virtuelle sélectionnée par le système d'exploitation et l'architecture.

Je ne sais pas dans quelle mesure cela s'applique à JDK 6.

 19
Author: pharsicle, 2013-03-18 07:15:06

IIRC la machine virtuelle du serveur effectue plus d'optimisations de hotspot au démarrage, elle s'exécute donc plus rapidement mais prend un peu plus de temps à démarrer et utilise plus de mémoire. La machine virtuelle cliente reporte la majeure partie de l'optimisation pour permettre un démarrage plus rapide.

Modifier pour ajouter: Voici quelques infos de Soleil, c'est pas très précis, mais de vous donner quelques idées.

 13
Author: Mike Akers, 2008-10-13 18:48:58

De la concurrence Goetz-Java dans la pratique:

  1. Conseil de débogage: Pour les applications serveur, assurez-vous de toujours spécifier le commutateur de ligne de commande-server JVM lors de l'appel de la JVM, même pour développement et test . La JVM du serveur effectue plus d'optimisation que la JVM cliente, telle que le levage de variables hors d'une boucle qui sont non modifié dans la boucle; code qui peut sembler fonctionner dans le l'environnement de développement (JVM client) peut interrompre le déploiement environnement (serveur JVM). Par exemple, avions-nous "oublié" de déclarer la variable endormie comme volatile dans la liste 3.4, la JVM du serveur pourrait hissez le test hors de la boucle (le transformant en une boucle infinie), mais la JVM cliente ne serait pas . Une boucle infinie qui apparaît dans le développement est beaucoup moins coûteux que celui qui n'apparaît que dans production.

Liste 3.4. Compter les moutons.

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

Mon accent. YMMV

 11
Author: Adam, 2016-03-10 10:29:43

IIRC, il implique des stratégies de collecte des ordures. La théorie est qu'un client et un serveur seront différents en termes d'objets de courte durée, ce qui est important pour les algorithmes GC modernes.

Voici un lien sur le mode serveur. Hélas, ils ne mentionnent pas le mode client.

Voici un lien très complet sur GC en général; ceci est un article plus basique. Je ne sais pas si l'une ou l'autre adresse-serveur vs-client, mais c'est du matériel pertinent.

À Pas De Peluches Juste Ken Sipe et Glenn Vandenburg font d'excellentes discussions sur ce genre de choses.

 4
Author: Michael Easter, 2008-10-13 18:57:26

Je n'ai remarqué aucune différence de temps de démarrage entre les 2, mais j'ai enregistré une amélioration très minime des performances de l'application avec "-server" (serveur Solaris, tout le monde utilisant SunRays pour exécuter l'application). C'était moins de 1,5.

 3
Author: Brian Knoblauch, 2008-10-13 18:45:07

La dernière fois que j'ai regardé cela, (et certes, il y a un certain temps), la plus grande différence que j'ai remarquée était dans la collecte des ordures.

IIRC:

  • La machine virtuelle de tas de serveur a un nombre différent de générations que la machine virtuelle cliente et un algorithme de récupération de place différent. Cela peut ne plus être vrai
  • La machine virtuelle du serveur alloue de la mémoire et ne la libère pas sur le système d'exploitation
  • La machine virtuelle du serveur utilisera des algorithmes d'optimisation plus sophistiqués, et donc avoir des besoins en temps et en mémoire plus importants pour l'optimisation

Si vous pouvez comparer deux machines virtuelles java, un client, un serveur à l'aide de l'outil jvisualvm, vous devriez voir une différence dans la fréquence et l'effet de la récupération de place, ainsi que dans le nombre de générations.

J'ai eu une paire de captures d'écran qui ont très bien montré la différence, mais je ne peux pas reproduire car j'ai une JVM 64 bits qui n'implémente que la machine virtuelle du serveur. (Et je ne peux pas être pris la peine de télécharger et disputer la version 32 bits sur mon système.)

Cela ne semble plus être le cas, après avoir essayé d'exécuter du code sur Windows avec des machines virtuelles serveur et client, il semble que j'obtienne le même modèle de génération pour les deux...

 1
Author: brice, 2013-03-22 17:27:01

Lors d'une migration de la version 1.4 vers la version 1.7("1.7.0_55").La chose que nous avons observée ici est qu'il n'y a pas de telles différences dans les valeurs par défaut attribuées aux paramètres heapsize|permsize|ThreadStackSize en mode client et serveur.

Au fait, ( http://www.oracle.com/technetwork/java/ergo5-140223.html). Ceci est l'extrait tiré du lien ci-dessus.

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

ThreadStackSize est plus élevé dans 1.7, tout en passant par le forum JDK ouvert, il y a des discussions qui ont déclaré frame la taille est un peu plus élevée dans la version 1.7. On pense qu'une différence réelle pourrait être possible à mesurer au moment de l'exécution en fonction de votre comportement de votre application

 1
Author: Nuwan Arambage, 2015-03-22 07:46:45