Question

Existe-t-il une réelle différence pratique entre " serveur-java " et "client-java"?

Tout ce que je peux trouver sur le site de Sun est vague

  

"-serveur démarre plus lentement mais devrait fonctionner plus vite".

Quelles sont les vraies différences? (Utilisation de JDK 1.6.0_07 actuellement.)

Était-ce utile?

La solution

Ceci est vraiment lié à HotSpot et aux valeurs par défaut de option ( Options de machine virtuelle Java HotSpot ) qui diffèrent entre les configurations client et serveur.

Extrait du chapitre 2 du livre blanc ( Architecture du moteur de performance Java HotSpot ):

  

Le kit JDK comprend deux types de machine virtuelle: une offre côté client et une machine virtuelle adaptée aux applications serveur. Ces deux solutions partagent la base de code de l'environnement d'exécution Java HotSpot, mais utilisent des compilateurs différents, adaptés aux caractéristiques de performances distinctement uniques des clients et des serveurs. Ces différences incluent la stratégie en ligne de compilation et les valeurs par défaut du tas.

     

Bien que les machines virtuelles serveur et client soient similaires, la machine virtuelle serveur a été spécialement conçue pour optimiser la vitesse de fonctionnement maximale. Il est destiné à l'exécution d'applications serveur de longue durée, qui nécessitent une vitesse de fonctionnement la plus rapide possible, supérieure à un temps de démarrage rapide ou à une taille réduite de la mémoire d'exécution.

     

Le compilateur de la machine virtuelle client sert de mise à niveau à la fois pour les compilateurs JIT (Just-in-time) et Classic-in-time utilisés par les versions précédentes du JDK. La machine virtuelle client offre de meilleures performances d'exécution 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'encombrement de la 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.

La différence réelle se situe donc également au niveau du compilateur:

  

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

     

La machine virtuelle serveur contient un compilateur adaptatif avancé qui prend en charge bon nombre des mêmes types d'optimisations effectuées par l'optimisation des compilateurs C ++, ainsi que des optimisations qui ne peuvent pas être réalisées par les compilateurs traditionnels, telles que l'inlignage agressif des 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 souple dans son approche et surpasse généralement même les techniques avancées d'analyse et de compilation statiques.

Remarque: publication de la mise à jour jdk6 10 (voir Notes de version de la mise à jour: Modifications apportées dans la version 1.6.0_10 ) pour tenter d’améliorer les temps de démarrage, mais pour une raison différente de celle des options de point chaud, étant présenté différemment avec un noyau beaucoup plus petit.

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

-client
  

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

Autres conseils

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

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

par défaut, -server , mais avec l'option -client , je reçois:

$ 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 la mémoire et des allocations initiales sont beaucoup plus élevées pour cette version java .

Cependant, ces valeurs peuvent changer pour différentes combinaisons d'architecture, de systèmes d'exploitation et de versions Jvm. Les versions récentes de jvm ont supprimé les indicateurs et supprimé de nombreuses distinctions entre serveur et client.

N'oubliez pas non plus que vous pouvez voir tous les détails d'un jvm en cours d'exécution à l'aide de jvisualvm . Ceci est utile si vous avez des utilisateurs ou des modules qui définissent JAVA_OPTS ou utilisent des scripts qui modifient les options de la ligne de commande. Cela vous permettra également de surveiller, en temps réel, l'utilisation de l'espace tas et permgen ainsi que de nombreuses autres statistiques.

Une différence que je viens de remarquer est que dans "client" Il semblerait que la machine virtuelle Java restitue au système d’exploitation de la mémoire non utilisée, alors qu’avec "serveur" mode, une fois que la machine virtuelle Java récupère la mémoire, elle ne la restitue pas. C’est ainsi qu’il apparaît de toute façon sur Solaris avec Java6 (avec prstat -Z pour voir la quantité de mémoire allouée à un processus).

Les systèmes -client et -server sont des fichiers binaires différents. Il s’agit essentiellement de deux compilateurs différents (JIT) 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 une faible empreinte de pas. Le système serveur est optimal pour les applications où les performances globales sont primordiales. 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 le code suivant 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 cours sont les mêmes dans les deux manches!

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

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

Il semble que l'optimazation plus agressive du système serveur supprime la boucle car elle comprend qu'elle n'exécute aucune action!

Référence

La documentation en ligne d’Oracle fournit des informations relatives à Java SE 7.

Sur la java - programme de lancement 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 -server , il est écrit:

  

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; l'option -server est donc implicite. Cela est sujet à changement dans une prochaine version.

La page Détection d'ordinateur de type serveur fournit des informations. sur lequel la machine virtuelle est sélectionnée par le système d'exploitation et l'architecture.

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

La machine virtuelle serveur IIRC effectue davantage d’optimisations de points chauds au démarrage, de sorte qu’elle s’exécute plus rapidement, mais prend un peu plus de temps à démarrer et utilise plus de mémoire. La machine virtuelle client diffère l'essentiel de l'optimisation pour permettre un démarrage plus rapide.

Modifier pour ajouter: Voici quelques informations de Sun, ce n'est pas très spécifique mais vous donnera quelques idées.

De Goetz - La concurrence de Java en pratique:

  
      
  1. Conseil de débogage: pour les applications serveur, veillez à toujours spécifier le commutateur de ligne de commande -server de la machine virtuelle Java lors de l’appel de la machine virtuelle, même pour.   développement et tests . La machine virtuelle Java du serveur effectue plus d'optimisation   JVM client, telles que le levage de variables d’une boucle qui sont   non modifié dans la boucle; code qui pourrait sembler fonctionner dans le   L’environnement de développement (JVM client) peut s’interrompre dans le déploiement   environnement (JVM du serveur). Par exemple, avions-nous & # 8220; oublié & # 8221; déclarer   la variable endormie étant volatile dans le Listing 3.4, la machine virtuelle Java du serveur pourrait   hisser le test hors de la boucle (en le transformant en une boucle infinie), mais   la machine virtuelle cliente ne le ferait 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.
  2.   
     

Listing 3.4. Compter les moutons.

     

  volatile booléenne endormie;   ...   pendant que (! endormi)      countSomeSheep ();

Mon emphase. YMMV

IIRC, cela 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 en mode serveur. Hélas, ils ne mentionnent pas le mode client.

Voici un lien très complet sur le GC en général; il s'agit d'un article plus élémentaire . Pas sûr que ce soit l'adresse -serveur vs -client, mais il s'agit de matériel pertinent.

Chez No Fluff Just Stuff, Ken Sipe et Glenn Vandenburg discutent tous les deux sur ce genre de choses.

Je n'ai pas remarqué de différence de temps de démarrage entre les deux, mais une amélioration très minime des performances de l'application avec "-server". (Serveur Solaris, toutes les personnes utilisant SunRays pour exécuter l'application). C'était moins de 1,5.

La dernière fois que j’y ai jeté un coup d’œil (et il est vrai que c’était il ya quelque temps), la plus grande différence que j’ai constatée était dans la collecte des ordures.

IIRC:

  • La machine virtuelle de tas du serveur a un nombre de générations différent de celui de la machine virtuelle client et un algorithme de récupération de place différent. Cela risque de ne plus être vrai
  • La machine virtuelle serveur allouera de la mémoire sans la libérer sur le système d'exploitation
  • La machine virtuelle serveur utilisera des algorithmes d'optimisation plus sophistiqués, ce qui nécessitera davantage de temps et de mémoire pour l'optimisation

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

J'ai une paire de captures d'écran qui montre très bien la différence, mais je ne peux pas reproduire car j'ai une machine virtuelle Java 64 bits qui implémente uniquement la machine virtuelle du serveur. (Et je ne me soucie pas non plus de télécharger et de manipuler la version 32 bits de mon système.)

Cela ne semble plus être le cas, après avoir essayé d'exécuter du code sous Windows avec des VM à la fois serveur et client, il me semble avoir le même modèle de génération pour les deux ...

Lorsque vous effectuez une migration de la version 1.4 à la version 1.7 ("1.7.0_55"). Ce que nous avons observé ici est qu’il n’existe pas de telles différences dans les valeurs par défaut affectées aux paramètres heapsize | permsize | ThreadStackSize dans client & amp; mode serveur.

Au fait, ( http://www.oracle.com/ technetwork / java / ergo5-140223.html ). C'est l'extrait extrait 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 la version 1.7, lors du forum Open JDK, des discussions ont indiqué que la taille de la trame est légèrement supérieure dans la version 1.7. On pense qu'il est possible de mesurer une différence réelle au moment de l'exécution en fonction du comportement de votre application

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top