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

O que um compilador JIT faz especificamente em oposição a um compilador não-JIT? Alguém pode dar uma descrição sucinta e fácil de entender?

    Um compilador JIT é executado depois que o programa é iniciado e compila o código (geralmente bytecode ou algum tipo de instruções de VM) rapidamente (ou just-in-time, como é chamado) em um formulário que normalmente é mais rápido, normalmente conjunto de instruções. Um JIT tem access a informações de tempo de execução dinâmicas, enquanto um compilador padrão não faz e pode fazer otimizações melhores, como funções inline que são usadas com freqüência.

    Isso está em contraste com um compilador tradicional que compila todo o código para a linguagem de máquina antes que o programa seja executado pela primeira vez.

    Parafraseando, os compiladores convencionais constroem o programa inteiro como um arquivo EXE ANTES da primeira vez que você o executa. Para programas de estilo mais recentes, um assembly é gerado com pseudocódigo (p-code). 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 de máquina (código m) que o processador baseado em Intel ou o que entender.

    No começo, um compilador era responsável por transformar uma linguagem de alto nível (definida como nível superior a assembler) em código de object (instruções de máquina), que seria então vinculada (por um linker) a 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 então seria interpretado (por um intérprete) para executar seu programa. Isso eliminou o código-object e os executáveis ​​e permitiu que esses idiomas fossem portáveis ​​para vários sistemas operacionais e plataformas de hardware. Pascal (que compilou para o P-Code) foi um dos primeiros; Java e C # são exemplos mais recentes. Eventualmente, o termo P-Code foi substituído por bytecode, uma vez que a maioria das pseudooperações são longas.

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

    JIT-Just in time a própria palavra diz quando é necessário (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 (linguagem intermediária) para C #, ByteCode para java].

    O código intermediário é convertido em linguagem de máquina apenas quando os códigos requeridos pelos aplicativos são convertidos somente em código de máquina.

    Comparação JIT vs Non-JIT:

    • No JIT nem todo o código é convertido em código de máquina primeiro uma parte do código que é necessário será convertida em código de máquina, então se um método ou funcionalidade chamado não estiver na máquina, então isso será transformado em código de máquina … ele reduz carga na CPU.

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

    Exemplos de JIT:

    1. No Java, o JIT está na JVM (Java Virtual Machine)
    2. Em C # está no CLR (Common Language Runtime)
    3. No Android, ele está em DVM (Dalvik Virtual Machine) ou ART (Android RunTime) em versões mais recentes.

    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 function é executada. Se esta contagem exceder um limite predefinido, o JIT compila o código em linguagem de máquina que pode ser executada diretamente pelo processador (ao contrário do caso normal em que o javac compila o código em bytecode e depois java – o interpretador interpreta esse bytecode linha por linha código de máquina e executa).

    Da próxima vez que esta function for calculada, o mesmo código compilado é executado novamente, diferentemente da interpretação normal, na qual o código é interpretado novamente linha por linha. Isso torna a execução mais rápida.

    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 seu compilador C médio, compilará todo o código para o 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á atrasando a execução do programa para o usuário.

    Após o código de byte (que é arquitetura neutra) ter sido 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. Então nós temos os compiladores JIT (just-in-time). Quando o byte tiver sido carregado na JVM (seu tempo de execução), todo o código será compilado em vez de interpretado, economizando tempo.

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

    O compilador JIT somente compila o código de bytes para código nativo equivalente na primeira execução. Em cada execução sucessiva, a JVM usa apenas 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 traduz o código de bytes linha por linha para que pareça que um aplicativo nativo está sendo executado.

    insira a descrição da imagem aqui

    Fonte

    Just In Time Compiler (JIT):
    Ele compila os bytecodes java em instruções de máquina dessa CPU específica.

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

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

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

    Não é necessário compilar o bytecode por 10 vezes repetidamente, 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. Assim, Just In Time (JIT) Compiler acompanha essas instruções e methods (como foi dito anteriormente) e compila essas partes do código de byte em código de máquina para um melhor desempenho.

    Outro exemplo semelhante, é que uma busca por um padrão usando "Expressão Regular" em uma lista de seqüências de caracteres / frases.

    Compilador JIT não compila todo o código para código de máquina. Ele compila código que possui um padrão semelhante em tempo de execução.

    Veja esta documentação da Oracle em Entender o JIT para ler mais.

    Você tem código que é compilado em alguma IL (linguagem intermediária). Quando você executa seu programa, o computador não entende esse código. Só entende o código nativo. Então o compilador JIT compila sua IL em código nativo na hora. Isso é feito no nível do método.

    Eu sei que este é um segmento antigo, mas otimização de tempo de execução é outra parte importante da compilation JIT que não parece ser discutida aqui. Basicamente, o compilador JIT pode monitorar o programa enquanto ele é executado para determinar formas de melhorar a execução. Então, ele pode fazer essas alterações dinamicamente – durante o tempo de execução. Otimização do Google JIT (javaworld tem um bom artigo sobre isso. )

    Jit significa just in time o compilador jit é um programa que transforma o código de byte java em uma instrução que pode ser enviada diretamente para o processador.

    Usando o compilador just in time do java (na verdade, um segundo compilador) na plataforma do sistema em particular, o bytecode entra em um código de sistema específico, uma vez que o código tenha sido compilado pelo jit complier, ele geralmente será 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.

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

    Os exemplos de código a seguir mostram como o JIT otimiza o código Java.

    Código antes da otimização

      class A { B b; public void newMethod() { y = b.get(); ...do stuff... z = b.get(); sum = y + z; } } class B { int value; final int get() { return value; } } 

    Código após otimização

     class A { B b; public void newMethod() { y = b.value; ...do stuff... sum = y + y; } } class B { int value; final int get() { return value; } } 

    Originalmente, o código continha duas chamadas para o método b.get (). Após a otimização, as duas chamadas de método são otimizadas em uma única operação de cópia de variável; ou seja, o código otimizado não precisa executar uma chamada de método para adquirir o valor do campo da class B.

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

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

    Vamos considerar o JIT usado na JVM,

    Por exemplo, os compiladores JIT JIT do HotSpot 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 voltadas para a arquitetura do sistema subjacente.

    Quando um método é escolhido para compilation, a JVM alimenta seu bytecode para o JIT (Just-In-Time Compiler). O JIT precisa entender a semântica e a syntax 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 trees de rastreamento, que se assemelha mais ao código de máquina do que ao bytecode. A análise e as otimizações são então realizadas nas trees do método. No final, as trees são traduzidas em código nativo.

    Uma tree de rastreamento é uma estrutura de dados usada na compilation de tempo de execução do código de programação. As trees de rastreamento são usadas em um tipo de compilador ‘just in time’ que rastreia a execução de código durante os pontos de access e o compila. Referir isso .

    Referir :

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

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

    Na verdade, a JVM executa etapas de compilation 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 compilation. Primeiro, faz uma chamada compilation estática do código-fonte Java ao bytecode. Então esse bytecode é passado para a JVM para execução. Mas a execução do bytecode é lenta, então a JVM mede a frequência com que o bytecode é executado e quando detecta um “hotspot” de código que é executado com muita frequência, executa compilation dinâmica do bytecode para machinecode do código “hotspot” (hotspot profiler). Então, efetivamente, hoje os programas Java são executados pela execução do machinecode.