Differenze reali tra & # 8220; java -server & # 8221; e & # 8220; java -client & # 8221 ;?

StackOverflow https://stackoverflow.com/questions/198577

  •  10-07-2019
  •  | 
  •  

Domanda

C'è qualche reale differenza pratica tra " java -server " e "java -client"?

Tutto quello che posso trovare sul sito di Sun è un vago

  

" -server si avvia più lentamente ma dovrebbe funzionare più veloce " ;.

Quali sono le reali differenze? (Attualmente utilizza JDK 1.6.0_07.)

È stato utile?

Soluzione

Questo è veramente collegato a HotSpot e ai valori di opzione predefiniti ( Opzioni VM HotSpot VM ) che differiscono tra configurazione client e server.

Da Capitolo 2 del white paper ( L'architettura Java HotSpot Performance Engine ):

  

JDK include due versioni della VM: un'offerta lato client e una VM ottimizzata per le applicazioni server. Queste due soluzioni condividono la base di codici dell'ambiente di runtime di Java HotSpot, ma utilizzano compilatori diversi che si adattano alle caratteristiche di prestazioni distintamente uniche di client e server. Queste differenze includono la politica di compilazione in linea e le impostazioni predefinite dell'heap.

     

Sebbene le VM Server e Client siano simili, la VM Server è stata appositamente ottimizzata per massimizzare la massima velocità operativa. È destinato all'esecuzione di applicazioni server a esecuzione prolungata, che richiedono la massima velocità operativa più che un tempo di avvio rapido o un footprint di memoria di runtime inferiore.

     

Il compilatore VM client funge da aggiornamento sia per i compilatori VM classici che per i just-in-time (JIT) utilizzati dalle versioni precedenti di JDK. La VM client offre prestazioni di runtime migliorate per applicazioni e applet. La VM client HotSpot Java è stata appositamente ottimizzata per ridurre i tempi di avvio dell'applicazione e il footprint di memoria, rendendola particolarmente adatta agli ambienti client. In generale, il sistema client è migliore per le GUI.

Quindi la vera differenza è anche a livello di compilatore:

  

Il compilatore VM client non tenta di eseguire molte delle ottimizzazioni più complesse eseguite dal compilatore nella VM server, ma in cambio richiede meno tempo per analizzare e compilare un pezzo di codice. Ciò significa che la VM client può avviarsi più rapidamente e richiede un ingombro di memoria inferiore.

     

La VM server contiene un compilatore adattivo avanzato che supporta molti degli stessi tipi di ottimizzazioni eseguite ottimizzando i compilatori C ++, nonché alcune ottimizzazioni che non possono essere eseguite dai compilatori tradizionali, come ad esempio l'inerzia aggressiva attraverso invocazioni di metodi virtuali. Questo è un vantaggio competitivo e prestazionale rispetto ai compilatori statici. La tecnologia di ottimizzazione adattiva è molto flessibile nel suo approccio e in genere supera anche le tecniche avanzate di analisi statica e compilazione.

Nota: la versione di jdk6 update 10 (vedi Note di rilascio dell'aggiornamento: modifiche in 1.6.0_10 ) hanno cercato di migliorare i tempi di avvio, ma per un motivo diverso rispetto alle opzioni dell'hotspot, essendo impacchettato in modo diverso con un kernel molto più piccolo.


G. Demecki sottolinea in i commenti che nelle versioni a 64 bit di JDK, l'opzione -client viene ignorata per molti anni.
Vedi Windows java comando :

-client
  

Seleziona la VM client HotSpot Java.
   Un JDK a 64 bit attualmente ignora questa opzione e utilizza invece la macchina virtuale Java Hotspot Server .

Altri suggerimenti

La differenza immediata più visibile nelle versioni precedenti di Java sarebbe la memoria allocata a un'applicazione -client rispetto a un'applicazione -server . Ad esempio, sul mio sistema Linux, ottengo:

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

come predefinito -server , ma con l'opzione -client ottengo:

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

quindi con -server la maggior parte dei limiti di memoria e delle allocazioni iniziali sono molto più alti per questa versione java .

Questi valori possono tuttavia cambiare per diverse combinazioni di architettura, sistemi operativi e versioni jvm. Le versioni recenti di jvm hanno rimosso i flag e spostato molte delle distinzioni tra server e client.

Ricorda anche che puoi vedere tutti i dettagli di un jvm in esecuzione usando jvisualvm . Ciò è utile se si dispone di utenti o moduli che impostano JAVA_OPTS o utilizzano script che modificano le opzioni della riga di comando. Questo ti permetterà anche di monitorare, in tempo reale, l'utilizzo dello spazio heap e permgen insieme a molte altre statistiche.

Una differenza che ho appena notato è che in " client " modalità, sembra che JVM restituisca effettivamente una memoria inutilizzata al sistema operativo, mentre con "server" modalità, una volta che la JVM acquisisce la memoria, non la restituirà. Ecco come appare su Solaris con Java6 (usando prstat -Z per vedere la quantità di memoria allocata a un processo).

i sistemi -client e -server sono binari diversi. Sono essenzialmente due diversi compilatori (JIT) che si interfacciano allo stesso sistema di runtime. Il sistema client è ottimale per applicazioni che richiedono tempi di avvio rapidi o ingombri ridotti, il sistema server è ottimale per applicazioni in cui le prestazioni complessive sono più importanti. In generale, il sistema client è più adatto per applicazioni interattive come le GUI

 inserisci qui la descrizione dell'immagine

Eseguiamo il seguente codice con entrambi gli switch:

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

Nota: il codice è stato compilato una sola volta! Le classi sono uguali in entrambe le sessioni!

Con -client:
 java.exe -client -classpath C: \ mywork \ classes com.blogspot.sdoulger.LoopTest
 Tempo trascorso: 766

Con -server:
 java.exe -server -classpath C: \ mywork \ classes com.blogspot.sdoulger.LoopTest
 Tempo trascorso: 0

Sembra che l'ottimizzazione più aggressiva del sistema server, rimuova il ciclo in quanto comprende che non esegue alcuna azione!

Riferimento

La documentazione online di Oracle fornisce alcune informazioni per Java SE 7.

Nella java - la pagina di avvio dell'applicazione Java per Windows , l'opzione -client viene ignorata in un JDK a 64 bit:

  

Seleziona la VM Java HotSpot Client. Un jdk a 64 bit attualmente ignora questa opzione e utilizza invece la VM Java HotSpot Server.

Tuttavia (per rendere le cose interessanti), in -server si afferma:

  

Seleziona la VM Java HotSpot Server. Su un jdk a 64 bit è supportata solo la VM Java HotSpot Server, quindi l'opzione -server è implicita. Questo è soggetto a modifiche in una versione futura.

La pagina Rilevazione macchine di classe server fornisce informazioni su quale VM è selezionata per sistema operativo e architettura.

Non so quanto si applica a JDK 6.

IIRC la VM del server esegue più ottimizzazioni di hotspot all'avvio, quindi funziona più velocemente ma richiede un po 'più di tempo per avviarsi e utilizza più memoria. La VM client difende gran parte dell'ottimizzazione per consentire un avvio più rapido.

Modifica per aggiungere: Ecco alcune informazioni da Sun, non è molto specifico ma ti darà alcune idee.

Da Goetz - Concorrenza Java in pratica:

  
      
  1. Suggerimento per il debug: per le applicazioni server, assicurarsi di specificare sempre l'opzione della riga di comando JVM -server quando si richiama JVM, anche per   sviluppo e test . Il server JVM esegue una maggiore ottimizzazione   rispetto al client JVM, come il sollevamento di variabili da un ciclo che lo sono   non modificato nel loop; codice che potrebbe sembrare funzionare nel file   l'ambiente di sviluppo (client JVM) può interrompere la distribuzione   ambiente (server JVM). Ad esempio, avevamo & # 8220; dimenticato & # 8221; dichiarare   la variabile addormentata come volatile nel Listato 3.4, il server JVM potrebbe   sollevare il test dal loop (trasformandolo in un loop infinito), ma   il client JVM non lo farebbe . Un ciclo infinito che si presenta in   lo sviluppo è molto meno costoso di quello che compare solo in   produzione.
  2.   
     

Elenco 3.4. Conteggio delle pecore.

     

  volatile booleano addormentato;   ...   mentre (! addormentato)      countSomeSheep ();

La mia enfasi. YMMV

IIRC, prevede strategie di raccolta dei rifiuti. La teoria è che un client e un server saranno diversi in termini di oggetti di breve durata, il che è importante per i moderni algoritmi GC.

Ecco un link in modalità server. Purtroppo, non menzionano la modalità client.

Ecco un link molto completo su GC in generale; questo è un un articolo più semplice . Non sono sicuro se address -server vs -client ma questo è materiale pertinente.

In No Fluff Just Stuff, sia Ken Sipe che Glenn Vandenburg fanno grandi chiacchiere su questo genere di cose.

Non ho notato alcuna differenza nel tempo di avvio tra i 2, ma ho registrato un miglioramento molto minimo nelle prestazioni dell'applicazione con "server". (Server Solaris, tutti usano SunRays per eseguire l'app). Quello era meno di 1.5.

L'ultima volta che ho dato un'occhiata a questo, (e devo ammettere che era un po 'di tempo fa) la più grande differenza che ho notato era nella raccolta dei rifiuti.

IIRC:

  • La VM heap del server ha un numero di generazioni diverso rispetto alla VM client e un algoritmo di garbage collection diverso. Questo potrebbe non essere più vero
  • La VM del server alloca la memoria e non la rilascia sul sistema operativo
  • La VM del server utilizzerà algoritmi di ottimizzazione più sofisticati e quindi avrà requisiti di memoria e tempo maggiori per l'ottimizzazione

Se puoi confrontare due VM Java, un client e un server utilizzando lo strumento jvisualvm , dovresti vedere una differenza nella frequenza e nell'effetto della raccolta dei rifiuti, così come nel numero di generazioni.

Avevo un paio di schermate che mostravano la differenza davvero bene, ma non riesco a riprodurre poiché ho una JVM a 64 bit che implementa solo la VM del server. (E non posso essere disturbato a scaricare e modificare la versione a 32 bit anche sul mio sistema.)

Questo non sembra più essere il caso, dopo aver provato a eseguire un po 'di codice su Windows con VM sia server che client, mi sembra di ottenere lo stesso modello di generazione per entrambi ...

Quando si esegue una migrazione dalla versione 1.4 alla 1.7 ("1.7.0_55"). La cosa che abbiamo osservato qui è che non ci sono tali differenze nei valori predefiniti assegnati ai parametri heapsize | permsize | ThreadStackSize in client & amp; modalità server.

A proposito, ( http://www.oracle.com/ technetwork / java / ergo5-140223.html ). Questo è lo snippet preso dal link sopra.

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

ThreadStackSize è più alto in 1.7, mentre si passa attraverso il forum Open JDK, ci sono discussioni che affermano che la dimensione del frame è leggermente più alta nella versione 1.7. Si ritiene che la reale differenza possa essere misurata in fase di esecuzione in base al comportamento della propria applicazione

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top