O que faz um compilador just-in-time (JIT)?

Respostas:

518

Um compilador JIT é executado após o início do programa e compila o código (normalmente bytecode ou algum tipo de instruções da VM) em tempo real (ou just-in-time, como é chamado) em um formato geralmente mais rápido, geralmente o nativo da CPU do host conjunto de instruções. Um JIT tem acesso a informações de tempo de execução dinâmico, enquanto um compilador padrão não pode e pode fazer otimizações melhores, como funções embutidas que são usadas com freqüência.

Isso contrasta com um compilador tradicional que compila todo o código na linguagem de máquina antes da execução do programa.

Parafraseando, os compiladores convencionais criam o programa inteiro como um arquivo EXE ANTES da primeira vez que você o executa. Para programas de estilo mais recentes, uma montagem é gerada com pseudocódigo (código-p). Somente DEPOIS de executar o programa no sistema operacional (por exemplo, clicando duas vezes em seu ícone) o compilador (JIT) entrará em ação e gerará o código da máquina (código m) que o processador baseado na Intel ou o que quer que ele entenda.

Mark Cidade
fonte
16
E, ao contrário do código interpretado, que começa a executar as instruções de bytecode ou VM imediatamente sem demora, mas executa as instruções mais lentamente que a linguagem de máquina.
Aaron
3
Um JIT é frequentemente usado com código interpretado para convertê-lo em linguagem de máquina, mas sim, o código puramente interpretado (sem nenhum JITting) é lento. Até o bytecode Java sem um JITter é realmente lento.
Mark Cidade
48
O alvo não precisa ser o código da máquina. O JRuby possui um compilador JIT que compila o código-fonte do Ruby no código de bytes Java após algumas invocações. Depois de outras invocações, o compilador JVM JIT entra em ação e compila o bytecode no código nativo.
Jörg W Mittag
4
Vale ressaltar que, como mencionado por Jörg, o JIT não é necessariamente invocado imediatamente. Freqüentemente, o código será interpretado até que seja determinado que valerá a pena JITting. Como o JITting pode introduzir atrasos, pode ser mais rápido NÃO JIT algum código se ele raramente for usado e, portanto, uma resposta rápida é mais importante que o tempo de execução geral.
23611 Adam Jaskiewicz
3
@ErikReppen: se uma nova máquina sair, compilar e otimizar um programa para essa nova máquina usando um compilador convencional provavelmente produzirá resultados mais rapidamente do que um JIT. Por outro lado, um JIT otimizado para essa nova máquina poderá otimizar o desempenho do código publicado antes da invenção da nova máquina .
Supercat 3/13
255

No começo, um compilador era responsável por transformar uma linguagem de alto nível (definida como nível superior ao assembler) em código de objeto (instruções de máquina), que seria então vinculado (por um vinculador) em um executável.

Em um ponto da evolução das linguagens, os compiladores compilariam uma linguagem de alto nível em pseudo-código, que seria então interpretado (por um intérprete) para executar seu programa. Isso eliminou o código do objeto e os executáveis ​​e permitiu que esses idiomas fossem portáveis ​​para vários sistemas operacionais e plataformas de hardware. Pascal (compilado no P-Code) foi um dos primeiros; Java e C # são exemplos mais recentes. Eventualmente, o termo P-Code foi substituído por bytecode, pois a maioria das pseudo-operações tem um byte de comprimento.

Um compilador Just-In-Time (JIT) é um recurso do interpretador de tempo de execução, que, em vez de interpretar o bytecode toda vez que um método é chamado, compila o bytecode nas instruções de código da máquina da máquina em execução e, em seguida, invoca código do objeto. Idealmente, a eficiência da execução do código do objeto superará a ineficiência de recompilar o programa toda vez que ele for executado.

Craig Trader
fonte
5
No entanto, esta frase "um compilador Just-In-Time (JIT) é um recurso do interpretador de tempo de execução" causa confusão; por exemplo, - stackoverflow.com/questions/16439512/...
Stephen C
11
Na verdade, o JIT era um complemento e você ainda pode desativá-lo usando o parâmetro -Xint no Java, portanto, é apenas um recurso.
Craig Trader
3
Eu não concordo plenamente. JIT não é evolução - é uma alternativa dos compiladores clássicos.
I486
1
O JIT é um passo no caminho evolutivo, desde interruptores mecânicos com fiação rígida até a especificação de critérios de pesquisa, dizendo "OK Google" para o seu telefone inteligente. O JIT atual disponível como parte do Java 7/8 está muito além do que estava disponível como parte do Java 2 - isso também é evolução.
Craig Trader
1
@ i486 - A Sun / Oracle (AFAIK) nunca enviou um compilador clássico ("antecipadamente") para Java que gera código nativo. É muito difícil argumentar que o JIT é uma alternativa ... quando pensam que é supostamente uma alternativa, nunca foi enviado. (I descontar o compilador GCJ AOT porque isso não era nada a ver com a Sun / Oracle, e não era uma solução completa, quer É certamente não viáveis agora..)
Stephen C
69

JIT - bem a tempo, a própria palavra diz quando é necessária (sob demanda)

Cenário típico:

O código fonte é completamente convertido em código de máquina

Cenário JIT:

O código fonte será convertido em linguagem assembly como estrutura [para ex IL (idioma intermediário) para C #, ByteCode para java].

O código intermediário é convertido em linguagem de máquina somente quando o aplicativo precisa que os códigos necessários sejam convertidos apenas em código de máquina.

Comparação JIT vs Não JIT:

  • No JIT, nem todo o código é convertido em código de máquina, primeiro uma parte do código necessária será convertida em código de máquina; se um método ou funcionalidade chamado não estiver na máquina, ele será transformado em código de máquina ... carga sobre a CPU.

  • Como o código da máquina será gerado no tempo de execução .... o compilador JIT produzirá o código da máquina otimizado para a arquitetura da CPU da máquina.

Exemplos JIT:

  1. Em Java, o JIT está na JVM (Java Virtual Machine)
  2. Em C #, está no CLR (Common Language Runtime)
  3. No Android, ele está no DVM (Dalvik Virtual Machine) ou ART (Android RunTime) nas versões mais recentes.
Durai Amuthan.H
fonte
7
O JIT oferece algumas vantagens especiais em estruturas com suporte para tipos genéricos reais; é possível definir um método genérico que seria capaz de produzir uma variedade ilimitada de tipos, cada um exigiria código de máquina diferente, mas apenas o JIT geraria código para os tipos realmente produzidos. Por outro lado, em C ++, é necessário que o compilador gere código para todos os tipos que um programa utilizará.
supercat
6
A JVM não codifica JIT na primeira vez em que é executada. Nas primeiras vezes, ele interpreta o bytecode. Então, se esse código for executado com bastante frequência, ele pode decidir incomodá-lo.
Njalj
1
Você está dizendo que JIT em Java é JVM. No entanto, já fornecemos o código compilado para a JVM, não é? Então ele compila novamente, você quer dizer?
Koray Tugay
@KorayTugay - Fornecemos Bytecodes para JVM e a JVM converterá parte disso em código de máquina sob demanda. Para que os recursos sejam salvos.
precisa saber é o seguinte
1
No Java, JIT não é JVM. É apenas uma parte disso.
Happs 13/03/2015
25

Como outros já mencionaram

JIT significa Just-in-Time, o que significa que o código é compilado quando necessário, não antes do tempo de execução.

Apenas para adicionar um ponto à discussão acima, a JVM mantém uma contagem de quantas vezes uma função é executada. Se essa contagem exceder um limite predefinido, o JIT compila o código na linguagem de máquina que pode ser executada diretamente pelo processador (diferente do caso normal em que o javac compila o código no bytecode e depois no java - o intérprete interpreta esse bytecode linha por linha, o converte em código de máquina e executa).

Também na próxima vez que essa função for calculada, o mesmo código compilado é executado novamente, diferente da interpretação normal na qual o código é interpretado novamente linha por linha. Isso torna a execução mais rápida.

Aniket Thakur
fonte
14

O compilador JIT compila apenas o código de bytes para código nativo equivalente na primeira execução. A cada execução sucessiva, a JVM apenas usa o código nativo já compilado para otimizar o desempenho.

insira a descrição da imagem aqui

Sem o compilador JIT, o interpretador da JVM converte o código de byte linha por linha para fazer parecer que um aplicativo nativo está sendo executado.

insira a descrição da imagem aqui

Fonte


fonte
1
Minha interpretação do JIT é que ele age como memorização, onde as funções usadas com frequência são 'armazenadas' e as despesas de compilação do bytecode java para o código dependente do ISA nativo são ignoradas. Se isso estiver correto, por que o java não compila completamente o código nativo desde o início? Isso reduziria qualquer tipo de compilação em tempo de execução e tornaria o java 'nativo' para a máquina?
Michael Choi
12

JIT significa Just-in-Time, o que significa que o código é compilado quando necessário, não antes do tempo de execução.

Isso é benéfico porque o compilador pode gerar código otimizado para sua máquina específica. Um compilador estático, como o compilador C comum, compilará todo o código no código executável na máquina do desenvolvedor. Portanto, o compilador executará otimizações com base em algumas suposições. Ele pode compilar mais lentamente e fazer mais otimizações porque não está retardando a execução do programa para o usuário.

Brian Lyttle
fonte
Por que os códigos compilados não são armazenados em algum lugar no computador do usuário para que, na próxima vez em que o aplicativo seja executado, o JIT não precise recompilá-los novamente?
Omerfarukdogan
Boas observações. É possível fazer isso, mas se é realmente benéfico depende da plataforma e do uso do aplicativo. A otimização JIT não é necessariamente a mesma que offline, ou otimização antecipada, portanto o benefício pode ser apenas 'não JITting', o que pode ou não ajudar muito.
Brian Lyttle
9

Depois que o código de byte (que é neutro em arquitetura) for gerado pelo compilador Java, a execução será manipulada pela JVM (em Java). O código de byte será carregado na JVM pelo carregador e, em seguida, cada instrução de byte será interpretada.

Quando precisamos chamar um método várias vezes, precisamos interpretar o mesmo código várias vezes e isso pode levar mais tempo do que o necessário. Portanto, temos os compiladores JIT (just-in-time). Quando o byte for carregado na JVM (seu tempo de execução), todo o código será compilado em vez de interpretado, economizando tempo.

Os compiladores JIT funcionam apenas durante o tempo de execução, portanto, não temos nenhuma saída binária.

Do utilizador
fonte
2
O código inteiro não é compilado quando carregado na JVM, pois há poucas informações (leia-se: guia) sobre como proceder para a compilação. Lembre-se de que o desempenho é o objetivo final. O JIT é bastante seletivo: monitorando e selecionando os métodos mais populares de otimização. E continua fazendo isso até que o nível máximo de otimização seja alcançado para métodos individuais.
Yaw Boakye
7

Compilador Just In Time (JIT):
Compila os bytecodes java nas instruções da máquina dessa CPU específica.

Por exemplo, se tivermos uma instrução loop em nosso código java:

while(i<10){
    // ...
    a=a+i;
    // ...
 }

O código do loop acima é executado 10 vezes se o valor de i for 0.

Não é necessário compilar o bytecode por 10 vezes novamente, pois a mesma instrução será executada por 10 vezes. Nesse caso, é necessário compilar esse código apenas uma vez e o valor pode ser alterado pelo número de vezes necessário. Portanto, o compilador Just In Time (JIT) rastreia essas instruções e métodos (como dito acima) e compila essas partes do código de bytes no código da máquina para obter melhor desempenho.

Outro exemplo semelhante é a busca por um padrão usando "Expressão Regular" em uma lista de cadeias / frases.

O JIT Compiler não compila todo o código no código da máquina. Ele compila código que possui um padrão semelhante no tempo de execução.

Consulte esta documentação da Oracle no Understand JIT para ler mais.

Anands23
fonte
"Não é necessário compilar o bytecode por 10 vezes repetidas vezes, pois a mesma instrução será executada por 10 vezes" - e um compilador comum? Compila esta peça várias vezes?
TT_
4

Você tem um código que é compilado em alguma IL (linguagem intermediária). Quando você executa o programa, o computador não entende esse código. Ele entende apenas o código nativo. Portanto, o compilador JIT compila sua IL em código nativo em tempo real. Isso é feito no nível do método.

Charles Graham
fonte
2
O que você quer dizer com "nível de método"?
Koray Tugay
4

Eu sei que esse é um thread antigo, mas a otimização do tempo de execução é outra parte importante da compilação JIT que não parece ser discutida aqui. Basicamente, o compilador JIT pode monitorar o programa enquanto ele é executado para determinar maneiras de melhorar a execução. Em seguida, ele pode fazer essas alterações rapidamente - durante o tempo de execução. Otimização do JIT do Google (o javaworld tem um bom artigo sobre isso ) .

eze
fonte
3

Um just in time compiler (JIT) é um software que recebe uma entrada não executável e retorna o código de máquina apropriado a ser executado. Por exemplo:

Intermediate representation    JIT    Native machine code for the current CPU architecture

     Java bytecode            --->        machine code
     Javascript (run with V8) --->        machine code

A conseqüência disso é que, para uma certa arquitetura de CPU, o compilador JIT apropriado deve ser instalado.

Compilador de diferenças, intérprete e JIT

Embora possa haver exceções em geral quando queremos transformar o código fonte em código de máquina, podemos usar:

  1. Compilador : pega o código fonte e retorna um executável
  2. Intérprete : Executa a instrução do programa por instrução. Ele pega um segmento executável do código-fonte e transforma esse segmento em instruções da máquina. Esse processo é repetido até que todo o código-fonte seja transformado em instruções da máquina e executado.
  3. JIT : Muitas implementações diferentes de um JIT são possíveis, no entanto, um JIT geralmente é uma combinação de um complemento e um intérprete. O JIT primeiro transforma dados intermediários (por exemplo, Java bytecode) que recebe na linguagem de máquina por meio de interpretação. Um JIT pode perceber quando uma determinada parte do código é executada com frequência e a compila para obter uma execução mais rápida.
Willem van der Veen
fonte
2

Jit significa just in time compiler jit é um programa que transforma o código de bytes java em instruções que podem ser enviadas diretamente ao processador.

O uso do compilador java just in time (na verdade, um segundo compilador) na plataforma específica do sistema cumpre o bytecode em um código específico do sistema, uma vez que o código foi recompilado pelo jit complier, ele geralmente é executado mais rapidamente no computador.

O compilador just-in-time vem com a máquina virtual e é usado opcionalmente. Ele compila o bytecode no código executável específico da plataforma que é executado imediatamente.

user3459027
fonte
2

A compilação just-in-time (JIT), (também tradução dinâmica ou compilação em tempo de execução ), é uma maneira de executar código de computador que envolve a compilação durante a execução de um programa - em tempo de execução - e não antes da execução .

A compilação de TI é uma combinação das duas abordagens tradicionais da tradução para código de máquina - compilação antecipada (AOT) e interpretação - e combina algumas vantagens e desvantagens de ambas. A compilação JIT combina a velocidade do código compilado com a flexibilidade da interpretação .

Vamos considerar o JIT usado na JVM,

Por exemplo, os compiladores HotSpot JVM JIT geram otimizações dinâmicas. Em outras palavras, eles tomam decisões de otimização enquanto o aplicativo Java está em execução e geram instruções de máquina nativas de alto desempenho direcionadas para a arquitetura do sistema subjacente.

Quando um método é escolhido para compilação, a JVM alimenta seu bytecode ao compilador Just-In-Time (JIT). O JIT precisa entender a semântica e a sintaxe do bytecode antes de poder compilar o método corretamente. Para ajudar o compilador JIT a analisar o método, seu bytecode é primeiro reformulado em uma representação interna chamada árvores de rastreio, que se assemelha mais ao código de máquina que ao bytecode. Análises e otimizações são realizadas nas árvores do método. No final, as árvores são traduzidas em código nativo.

Uma árvore de rastreamento é uma estrutura de dados usada na compilação do código de programação em tempo de execução. As árvores de rastreamento são usadas em um tipo de 'compilador just in time' que rastreia a execução do código durante os pontos de acesso e o compila. Consulte isso .

Referir :

prime
fonte
1

Um compilador não JIT pega o código-fonte e o transforma em código de bytes específico da máquina no momento da compilação. Um compilador JIT pega o código de byte independente da máquina que foi gerado no tempo de compilação e o transforma em código de byte específico da máquina no tempo de execução. O compilador JIT usado por Java é o que permite que um único binário seja executado em várias plataformas sem modificação.


fonte
0

20% do código de bytes é usado 80% do tempo. O compilador JIT obtém essas estatísticas e otimiza esses 20% do código de bytes para executar mais rapidamente, adicionando métodos em linha, remoção de bloqueios não utilizados etc. e também criando o código de bytes específico para essa máquina. Estou citando este artigo, achei útil. http://java.dzone.com/articles/just-time-compiler-jit-hotspot

Santosh budhe
fonte
Não sei por que isso foi marcado como -1. Acho que o ponto aqui é que as estatísticas de tempo de execução são usadas para ajudar a otimizar.
eze
Sim, mas a resposta não foi assim. Literalmente, o JIT não otimiza os 20% mais quentes do código.
mabraham
0

JIT refere-se ao mecanismo de execução em algumas das implementações da JVM, uma que é mais rápida, mas requer mais memória, é um compilador just-in-time. Nesse esquema, os bytecodes de um método são compilados no código de máquina nativo na primeira vez em que o método é chamado. O código da máquina nativa para o método é armazenado em cache, para que possa ser reutilizado na próxima vez que o mesmo método for chamado.

Venkata Santhosh Piduri
fonte
2
Eu evitaria responder perguntas como essa se você não fornecer algo novo / melhor. Se você tiver alguma reação, é provavelmente um voto negativo ou crítica: sua resposta é imprecisa. "JIT" não se limita a uma Java Virtual Machine , "mais rápido, mas usa mais memória" é um efeito provável, mas não inerente ao conceito de JIT, e os métodos geralmente não são compilados na primeira chamada, mas depois de vários quando fica claro que O tempo gasto em JIT'ing é vantajoso em geral.
zapl
0

A JVM realmente executa etapas de compilação durante o tempo de execução por motivos de desempenho. Isso significa que o Java não possui uma separação limpa de execução de compilação. Primeiro, ele faz a chamada compilação estática do código-fonte Java para o bytecode. Em seguida, esse bytecode é passado para a JVM para execução. Mas a execução do bytecode é lenta, portanto, a JVM mede com que freqüência o bytecode é executado e quando detecta um "ponto ativo" de código executado com muita frequência, ele realiza a compilação dinâmica do bytecode para o código de máquina do código "hotspot" (criador de perfil de ponto ativo). Hoje, os programas Java são executados de maneira tão eficaz pela execução do código de máquina.

hi.nitish
fonte
0

O compilador Just In Time, também conhecido como compilador JIT, é usado para melhorar o desempenho em Java. Está ativado por padrão. É uma compilação feita no momento da execução, bem antes. Java popularizou o uso do compilador JIT, incluindo-o na JVM.

Ganesh Giri
fonte