Pergunta

Existe alguma diferença prática real entre "java -server" e "java -client"?

Tudo o que posso encontrar no site da Sun é uma vaga

"- servidor começa mais lento, mas deve correr mais rápido".

Quais são as diferenças reais? (Usando o JDK 1.6.0_07 atualmente.)

Foi útil?

Solução

Este é realmente ligado ao HotSpot e o padrão valores de opção ( Opções Java HotSpot VM ) que diferem entre cliente e configuração do servidor.

A partir Capítulo 2 do whitepaper ( O Java HotSpot Performance Engine Architecture):

O JDK inclui dois sabores da VM - uma oferta do lado do cliente, e uma VM atento para aplicações de servidor. Estas duas soluções compartilhar a base de código Java Runtime Environment HotSpot, mas usar diferentes compiladores que são adequados para as características de desempenho distintamente únicos de clientes e servidores. Essas diferenças incluem a política de compilação inlining e padrões heap.

Embora o servidor eo cliente VMs são semelhantes, o VM Server foi especialmente afinado para maximizar a velocidade operacional máxima. Ele é destinado a execução de aplicativos de servidor de longa duração, que precisam a velocidade de operação mais rápida possível mais do que um rápido tempo de arranque ou menor consumo de memória de tempo de execução.

O compilador cliente VM serve como um upgrade, tanto para o VM clássico e os just-in-time (JIT) compiladores usados ??por versões anteriores do JDK. As ofertas do cliente VM melhorou executar o desempenho do tempo para aplicações e applets. O Java HotSpot cliente VM foi especialmente afinado para reduzir aplicação em tempo de arranque e consumo de memória, tornando-o particularmente adequado para ambientes de clientes. Em geral, o sistema cliente é melhor para GUIs.

Assim, a diferença real também está no nível do compilador:

O compilador cliente VM não tenta executar muitas das otimizações mais complexos realizados pelo compilador na VM Server, mas em troca, exige menos tempo para analisar e compilar um pedaço de código. Isto significa que a VM Cliente pode iniciar-se mais rápido e requer um menor consumo de memória.

O VM Server contém um compilador adaptativa avançada que suporta muitos dos mesmos tipos de otimizações realizadas por meio da otimização compiladores C ++, bem como algumas otimizações que não pode ser feito por compiladores tradicionais, como inlining agressivo através de chamadas de método virtual. Esta é uma vantagem competitiva e desempenho ao longo compiladores estáticos. tecnologia de otimização de adaptação é muito flexível na sua abordagem, e normalmente supera técnicas de análise estática e compilação mesmo avançados.

Nota: O lançamento do jdk6 atualização 10 (veja atualização Release Notes:. Mudanças na 1.6.0_10 ) tentou melhorar o tempo de inicialização, mas por um motivo diferente do que as opções de hotspots, sendo embalado de forma diferente com um kernel muito menor


G. Demecki pontos fora em os comentários que em versões do JDK de 64 bits, a opção -client é ignorada por muitos anos.
Consulte o Windows comando java :

-client

Seleciona o Java HotSpot cliente VM.
A 64 bits JDK atualmente ignora esta opção e, em vez usa o Hotspot VM Server Java .

Outras dicas

A diferença imediata mais visível em versões antigas do Java seria a memória alocada para um -client ao contrário de um aplicativo -server. Por exemplo, no meu sistema Linux, eu recebo:

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

, uma vez que o padrão é -server, mas com a opção -client eu recebo:

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

assim com -server a maioria dos limites de memória e as verbas iniciais são muito mais elevados para esta versão java.

Estes valores podem mudar para diferentes combinações de arquitetura, sistemas operacionais e versões de JVM no entanto. As versões recentes do JVM ter removido bandeiras e removeu muitas das distinções entre o servidor eo cliente.

Lembre-se também que você pode ver todos os detalhes de um jvm execução usando jvisualvm. Isso é útil se você tiver usuários que ou módulos que estabeleceu JAVA_OPTS ou usar scripts que mudam as opções de linha de comando. Isso também permitirá que você monitorar, em tempo real, pilha e permgen a utilização do espaço, juntamente com muitas outras estatísticas.

Uma diferença Eu só notei é que no modo "cliente", parece que a JVM realmente dá alguns de volta a memória não utilizada para o sistema operacional, enquanto que com o modo de "servidor", uma vez que a JVM agarra a memória, ele ganhou' t devolvê-lo. Isso é como ele aparece no Solaris com Java6 qualquer maneira (usando prstat -Z para ver a quantidade de memória alocada para um processo).

os sistemas -client e -server são diferentes binários. Eles são essencialmente dois compiladores diferentes (EIC) de interface com o mesmo sistema de execução. O sistema cliente é ideal para aplicações que necessitam de tempos de inicialização rápida ou pequenas pegadas, o sistema do servidor é ideal para aplicações onde o desempenho geral é mais importante. Em geral, o sistema cliente é mais adequado para aplicações interativas, como GUIs

 entrar descrição da imagem aqui

Nós execute o seguinte código com ambos os interruptores:

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: O código é compilado apenas uma vez! As classes são os mesmos em ambas as corridas!

Com -client:
java.exe -client -classpath C: \ MYWORK \ classes com.blogspot.sdoulger.LoopTest
Tempo gasto: 766

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

Parece que o optimazation mais agressiva do sistema de servidor, remova o loop por entender que ele não executar qualquer ação!

de Referência

IIRC o servidor VM faz mais otimizações hotspot na inicialização para que ele corre mais rápido, mas demora um pouco mais para começar e usa mais memória. Os clientes VM adia a maioria da otimização para permitir a inicialização mais rápida.

Editar para adicionar: Veja aqui algumas informações da Sun, não é muito específica, mas vai lhe dar algumas idéias.

De Goetz - Java Concurrency in Practice:

  1. Depuração dica: Para aplicações de servidor, certifique-se sempre especificar a opção -server JVM linha de comando ao invocar a JVM, mesmo para desenvolvimento e teste . O servidor JVM realiza mais de otimização do que o cliente JVM, como elevação variáveis ??fora de um loop que são não modificado no circuito; código que pode parecer trabalho no ambiente de desenvolvimento (JVM cliente) pode quebrar na implantação ambiente (JVM servidor). Por exemplo, se tivéssemos “esquecido” para declarar a variável dormindo tão volátil na Listagem 3.4, do servidor JVM poderia talha o teste fora do circuito (transformando-a num ciclo infinito), mas o cliente JVM não faria . Um ciclo infinito que aparece em desenvolvimento é muito menos dispendioso do que aquele que só aparece em produção.

Listagem 3.4. Contando carneiros.

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

A minha ênfase. YMMV

IIRC, envolve estratégias de coleta de lixo. A teoria é que um cliente e servidor será diferente em termos de objetos de vida curta, o que é importante para algoritmos GC modernos.

Aqui está um link no modo de servidor. Infelizmente, eles não mencionam modo cliente.

Aqui está um link muito completa sobre GC em geral; este é um mais básico artigo . Não tenho certeza se qualquer -server endereço vs -client mas isso é material relevante.

No No Fluff apenas coisas, tanto Ken Sipe e Glenn Vandenburg fazer grandes conversas sobre esse tipo de coisa.

Eu não notei qualquer diferença no tempo de inicialização entre a 2, mas com clock uma melhoria muito mínimo em desempenho de aplicativo com "-server" (servidor Solaris, todos usando raios solares para executar o aplicativo). Que estava sob 1.5.

A última vez que tinha um olhar para isso, (e assumidamente foi um tempo atrás) a maior diferença que notei foi na coleta de lixo.

IIRC:

  • O servidor pilha VM tem um número differnt das gerações que a VM Cliente, e um algoritmo de coleta de lixo diferente. Isto pode não ser mais verdade
  • O servidor VM irá alocar memória e não liberá-lo para o sistema operacional
  • O servidor VM usará algoritmos de otimização mais sofisticados e, portanto, têm maiores requisitos de tempo e memória para otimização

Se você pode comparar dois java VMs, um cliente, um servidor usando o href="http://visualvm.java.net/" rel="nofollow"> ferramenta , você deve ver uma diferença na frequência e efeito da coleta de lixo, bem como no número de gerações.

eu tinha um par de imagens que mostravam a diferença muito bem, mas eu não posso reproduzir como eu tenho um 64 bit JVM que só implementa o servidor VM. (E eu não posso ser incomodado para fazer o download e disputar a versão de 32 bit no meu sistema bem.)

Este não parece ser o caso anymore, ter tentado executar algum código em janelas com servidor e cliente VMs, eu parecem ter o mesmo modelo de geração tanto para ...

Ao fazer uma migração de 1,4 a 1,7 ( "1.7.0_55") coisa version.The que observamos aqui é, não existe tal diferenças de valores padrão atribuídos a heapsize | permsize | parâmetros ThreadStackSize em modo de cliente e servidor.

A propósito, ( http://www.oracle.com/ technetwork / java / ergo5-140223.html ). Este é o trecho retirado do link acima.

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

ThreadStackSize é maior em 1,7, ao atravessar fórum aberto JDK, há discussões qual o tamanho quadro indicado é um pouco maior em 1,7 versão. Acredita-se diferença real poderia ser possível medir em tempo de execução com base no seu comportamento do seu aplicativo

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top