Sobre JVM, como é o funcionamento de algumas coisas dentro dela?

Estou criando este tópico para discutirmos sobre JVM.
Eu tenho duvidas sobre como funciona a parte interna do jVM. Gostaria de saber por exemplo, como que o java interpreta este codigo:

class testing{ public static void main(String[] args){ int x = 0, y = 0; if(x == 0 && y < 1){ System.out.println("Verdade"); } } }

A logica booleana AND ( E ) eu entendo mas como que o java interpreta o ‘==’, ‘<’ e ‘>’ internamente, podem me falar sobre bits, eu entendo um pouco. Gostaria de saber juntamente como que o JVM acessa por exemplo a variavel x que eu declarei la em cima, e se por acaso eu sobrescrever-la, sendo x = 3, como é trocado estes valores binarios?
E vamos discutir também sobre este assunto, que julga ser bem interessante.

Obrigado !

A JVM é um conjunto de compiladores, coletores de lixo e mais algumas ferramentas.

O seu bytecode é utilizado pelo jit e a partir dele o mesmo é otimizado e compilado para assembly. Java não é mais interpretado hà anos.

1 curtida

Caramba não tinha ideia q acontecia isto, mas da mesma forma, como que a Maquiina virtual faz aqulas operações e acessa variaveis que eu pgtei ali, alguem poderia me explicar mais ou menos?!

OBS: O que é um Jit ?!

eu não sabia disso. me tira uma duvida… quando o código é “compilado” para assembler?

[quote=Vinicius Zibetti Resko]Estou criando este tópico para discutirmos sobre JVM.
Eu tenho duvidas sobre como funciona a parte interna do jVM. Gostaria de saber por exemplo, como que o java interpreta este codigo:

class testing{
    public static void main(String[] args){
       int x = 0, y = 0;
       if(x == 0 && y < 1){
          System.out.println("Verdade");
       }
     }
}[/code]
[b]
A logica booleana AND ( E ) eu entendo mas como que o java interpreta o '==', '<' e '>' internamente, podem me falar sobre bits, eu entendo um pouco. Gostaria de saber juntamente como que o JVM acessa por exemplo a variavel x que eu declarei la em cima, e se por acaso eu sobrescrever-la, sendo x = 3, como é trocado estes valores binarios?
E vamos discutir também sobre este assunto, que julga ser bem interessante.[/b]

Obrigado ![/quote]

JVM é orientada a pilha diferentemente do jeitão "assembler" das coisas.
Imagine que um código escrito em C para plataforma x86 que gerá um assembler assim:
[code]add eax, edx
mov ecx, eax[/code]
O "assembler" Java (bytecode) gerado é bem diferente:
[code]0 iload_1
1 iload_2
2 iadd
3 istore_3

Um exemplo mais real, código Java:

for (int i = 2; i < 1000; i++) { for (int j = 2; j < i; j++) { if (i % j == 0) continue outer; } System.out.println (i); }

Gerá esse bytecode:

0: iconst_2 1: istore_1 2: iload_1 3: sipush 1000 6: if_icmpge 44 9: iconst_2 10: istore_2 11: iload_2 12: iload_1 13: if_icmpge 31 16: iload_1 17: iload_2 18: irem 19: ifne 25 22: goto 38 25: iinc 2, 1 28: goto 11 31: getstatic #84; //Field java/lang/System.out:Ljava/io/PrintStream; 34: iload_1 35: invokevirtual #85; //Method java/io/PrintStream.println:(I)V 38: iinc 1, 1 41: goto 2 44: return
Para saber o que cada uma dessas instruções signficam visite http://java.sun.com/docs/books/jvms/second_edition/html/Overview.doc.html#7143

E pra te ajudar a entender melhor a especificação da VM!
Fonte: http://en.wikipedia.org/wiki/Java_bytecode

JIT irá ou não recompilar dinamicamente seu bytecode para dar um gâs na perfomance! Em tempo de execução ele percebe inteligentemente um código que pode ser otimizado ou reescrito para “assembler” e otmiza aquela parte tipo um translator, tais conjuntos de instruções podem ser descritas em x86 instruções. Mas o JIT é um passo além de um simples recompilador… isso tudo eu acho que funciona assim,não mando muito bem com VM a única vm que conheço é o chip8 rsrsr.

1 curtida

Também é uma boa ler os artigos do Goetz:
http://www.briangoetz.com/pubs.html

Não fala exatamente sobre conversão do bytecode em código de máquina, porém, explica como funciona o garbage collector, sincronização e outros aspectos importantes da VM.

Vale lembrar também que cada VM pode conter otimizações específicas, para o local onde ela roda. Então, um mesmo bytecode pode ser compilado de N maneiras diferentes, desde que elas funcionem de maneira idêntica em cada plataforma.

1 curtida

Acredito que quando a JVM determina que um metodo é chamado constantemente. O HotSpot (JVM da Sun/Oracle) tem um argumento que determina depois de quantas execuções um metodo é compilado para codigo nativo.

Os artigos do Goetz que citei ali em cima também falam sobre a Hotspot compilation. Para quem não sabe, o Brian Goetz é um dos pais da linguagem Java.

O LLVM é um compilador e otimizador de assembly que está presente na maioria das máquinas virtuais que possuem um jit hoje.
http://llvm.org/

Os passos da execução de um programa java são.

  1. Javac - sourcecode para bytecode
  2. Hotspot e jit - compilação para assembly
  3. llvm - otimização do assembly

Por isso o código java roda tão rápido como um c++.

Hoje a jvm é um cojunto de ferramentas, e incluso um compilador realmente muito poderoso, que gera código enxuto(Apesar de possuir alguns problemas claro).

[quote=Vinicius Zibetti Resko]Caramba não tinha ideia q acontecia isto, mas da mesma forma, como que a Maquiina virtual faz aqulas operações e acessa variaveis que eu pgtei ali, alguem poderia me explicar mais ou menos?!

OBS: O que é um Jit ?![/quote]

O JIT(Just in Time) é um compilador dinâmico que consegue recriar o executável com base em estatísticas cedidas pelo hotspot. Isso quer dizer que a jvm pode melhorar o seu programa de tempos em tempos a medida que ele é executado

[quote=ViniGodoy]Também é uma boa ler os artigos do Goetz:
http://www.briangoetz.com/pubs.html

Não fala exatamente sobre conversão do bytecode em código de máquina, porém, explica como funciona o garbage collector, sincronização e outros aspectos importantes da VM.

Vale lembrar também que cada VM pode conter otimizações específicas, para o local onde ela roda. Então, um mesmo bytecode pode ser compilado de N maneiras diferentes, desde que elas funcionem de maneira idêntica em cada plataforma.[/quote]

Apenas o bytecode é padronizado. O assembly no final é referente a determinada arquitetura do hardware. Dá para imaginar a jvm de um grosso modo como um compilador inteligente e mantenedor de processos.

Não sabia disso, achei que ainda era interpretado.

Isso explica muita coisa.

Ainda que a VM interpretasse todo bytecode, não seria correto chamar o Java de linguagem interpretada. O termo mais correto seria linguagem mista.

Isto pq o assembly do bytecode é muito enxuto, praticamente não exige verificações que um compilador faria (sintáticas, semânticas e lexicas). Ele também tem um conjunto bastante reduzido de instruções, facilmente avaliaveis. É como se fosse um pseudo-código de máquina. Isso garante uma interpretação milhares de vezes mais rápida do que um interpretador faz numa linguagem diretamente, como é o caso do JavaScript ou do PHP.

Nossa quanto conhecimento aqui hein…

Obrigado, eu consegui entender algumas coisa interessantes.