Cosa fa un compilatore just-in-time (JIT)?


Risposte:


518

Un compilatore JIT viene eseguito dopo l'avvio del programma e compila il codice (solitamente bytecode o qualche tipo di istruzioni VM) al volo (o just-in-time, come viene chiamato) in un modulo che è solitamente più veloce, in genere nativo della CPU host set di istruzioni. Un JIT ha accesso a informazioni dinamiche sul runtime, mentre un compilatore standard no e può apportare migliori ottimizzazioni come funzioni integrate utilizzate frequentemente.

Questo è in contrasto con un compilatore tradizionale che compila tutto il codice in linguaggio macchina prima che il programma è prima esecuzione.

Per parafrasare, i compilatori convenzionali creano l'intero programma come file EXE PRIMA della prima esecuzione. Per i programmi di stile più recenti, viene generato un assembly con pseudocodice (codice p). Solo DOPO l'esecuzione del programma sul sistema operativo (ad esempio, facendo doppio clic sulla sua icona) il compilatore (JIT) avvierà e genererà il codice macchina (codice m) che il processore basato su Intel o qualunque cosa capirà.


16
Contrariamente al codice interpretato, che inizia a eseguire immediatamente il bytecode o le istruzioni della VM, ma eseguirà le istruzioni più lentamente del linguaggio macchina.
Aaron,

3
Un JIT viene spesso utilizzato con codice interpretato per convertirlo in linguaggio macchina, ma sì, il codice interpretato in modo puro (senza JITting) è lento. Anche il bytecode Java senza JITter è molto lento.
Mark Cidade,

48
Tuttavia, l'obiettivo non deve essere il codice macchina. JRuby ha un compilatore JIT che compilerà il codice sorgente Ruby in bytecode Java dopo un paio di invocazioni. Quindi, dopo un'altra coppia di invocazioni, il compilatore JVM JIT avvia e compila il bytecode in codice nativo.
Jörg W Mittag,

4
Vale la pena notare che, come indicato da Jörg, la JIT non è necessariamente invocata immediatamente. Spesso, il codice viene interpretato fino a quando non viene stabilito che varrà la pena JITting. Poiché JITting può introdurre ritardi, potrebbe essere più veloce NON JIT un po 'di codice se viene utilizzato raramente e quindi una risposta rapida è più importante del runtime complessivo.
Adam Jaskiewicz,

3
@ErikReppen: se esce una nuova macchina, compilare e ottimizzare un programma per quella nuova macchina usando un compilatore convenzionale probabilmente produrrà risultati più velocemente di un JIT. D'altra parte, un JIT ottimizzato per quella nuova macchina sarà in grado di ottimizzare le prestazioni del codice pubblicato prima dell'invenzione della nuova macchina .
supercat

255

All'inizio, un compilatore era responsabile della trasformazione di un linguaggio di alto livello (definito come livello superiore dell'assemblatore) in codice oggetto (istruzioni macchina), che sarebbe quindi stato collegato (da un linker) in un eseguibile.

Ad un certo punto dell'evoluzione delle lingue, i compilatori compilerebbero un linguaggio di alto livello in pseudo-codice, che verrebbe quindi interpretato (da un interprete) per eseguire il programma. Ciò ha eliminato il codice oggetto e gli eseguibili e ha permesso a queste lingue di essere trasferite su più sistemi operativi e piattaforme hardware. Pascal (compilato in P-Code) è stato uno dei primi; Java e C # sono esempi più recenti. Alla fine il termine P-Code è stato sostituito con bytecode, poiché la maggior parte delle pseudo-operazioni sono lunghe un byte.

Un compilatore Just-In-Time (JIT) è una caratteristica dell'interprete di runtime, che invece di interpretare il bytecode ogni volta che viene invocato un metodo, compila il bytecode nelle istruzioni del codice macchina della macchina in esecuzione e quindi invoca questo codice oggetto invece. Idealmente l'efficienza dell'esecuzione del codice oggetto supererà l'inefficienza della ricompilazione del programma ogni volta che viene eseguito.


5
Tuttavia, questa frase "un compilatore Just-In-Time (JIT) è una caratteristica dell'interprete di runtime" provoca confusione; ad es. - stackoverflow.com/questions/16439512/…
Stephen C,

11
In realtà, JIT era un componente aggiuntivo e puoi ancora disabilitarlo usando il parametro -Xint su Java, quindi è solo una funzione.
Craig Trader,

3
Non sono pienamente d'accordo. JIT non è evoluzione, è alternativa ai compilatori classici.
i486,

1
JIT è un passo avanti nel percorso evolutivo dagli interruttori meccanici a cablaggio fisso alla specifica dei criteri di ricerca pronunciando "OK Google" sul tuo smartphone. L'attuale JIT disponibile come parte di Java 7/8 fa passi da gigante rispetto a quanto era disponibile come parte di Java 2 - anche questa è evoluzione.
Craig Trader,

1
@ i486 - Sun / Oracle non hanno mai (AFAIK) un compilatore classico ("in anticipo") per Java che genera codice nativo. È una tesi sostenere che JIT è un'alternativa ... quando pensano che sia presumibilmente un'alternativa per non è mai stata spedita. (Sconto il compilatore AJ GCJ perché non aveva nulla a che fare con Sun / Oracle, e non era nemmeno una soluzione completa. Ora è certamente non praticabile.)
Stephen C

69

JIT-Just in time la stessa parola dice quando è necessario (su richiesta)

Scenario tipico:

Il codice sorgente viene completamente convertito in codice macchina

Scenario JIT:

Il codice sorgente verrà convertito in linguaggio assembly come struttura [per ex IL (linguaggio intermedio) per C #, ByteCode per java].

Il codice intermedio viene convertito in linguaggio macchina solo quando l'applicazione richiede che i codici richiesti vengano convertiti solo in codice macchina.

Confronto JIT vs Non JIT:

  • In JIT non tutto il codice viene convertito in codice macchina prima una parte del codice necessario verrà convertita in codice macchina, quindi se un metodo o una funzionalità chiamata non è presente nella macchina, verrà trasformato in codice macchina ... carico sulla CPU.

  • Poiché il codice macchina verrà generato in fase di esecuzione ... il compilatore JIT produrrà un codice macchina ottimizzato per l'esecuzione dell'architettura della CPU della macchina.

Esempi JIT:

  1. In Java JIT è in JVM (Java Virtual Machine)
  2. In C # è in CLR (Common Language Runtime)
  3. In Android è in DVM (Dalvik Virtual Machine) o ART (Android RunTime) nelle versioni più recenti.

7
JIT offre alcuni vantaggi speciali nei framework con supporto per tipi generici reali; è possibile definire un metodo generico che sarebbe in grado di produrre una gamma illimitata di tipi, ognuno richiederebbe un codice macchina diverso, ma solo JIT genererà il codice per i tipi effettivamente prodotti. Al contrario, in C ++ è necessario che il compilatore generi codice per tutti i tipi che un programma utilizzerà mai.
supercat

6
JVM non codifica JIT la prima volta che lo esegue. Le prime volte interpreta il bytecode. Quindi, se quel codice viene eseguito abbastanza spesso, potrebbe decidere di disturbare JIT.
ninjalj,

1
Stai dicendo che JIT in Java è JVM. Tuttavia, forniamo già il codice compilato a JVM, non è vero? Quindi lo compila di nuovo, vuoi dire?
Koray Tugay,

@KorayTugay - Forniamo Bytecodes in JVM e JVM convertirà parte di quello in codice macchina su richiesta. Così le risorse vengono salvate.
Durai Amuthan,

1
In Java JIT non è JVM. È solo una parte di esso.
Happs

25

Come altri hanno già detto

JIT sta per Just-in-Time, il che significa che il codice viene compilato quando è necessario, non prima del runtime.

Solo per aggiungere un punto alla discussione precedente, JVM mantiene un conteggio su quante volte viene eseguita una funzione. Se questo conteggio supera un limite predefinito, JIT compila il codice in linguaggio macchina che può essere eseguito direttamente dal processore (diversamente dal caso normale in cui javac compila il codice in bytecode e quindi java - l'interprete interpreta questo bytecode riga per riga lo converte in codice macchina ed esegue).

Anche la prossima volta che questa funzione viene calcolata, lo stesso codice compilato viene eseguito nuovamente a differenza della normale interpretazione in cui il codice viene interpretato di nuovo riga per riga. Questo rende l'esecuzione più veloce.


14

Il compilatore JIT compila il codice byte solo in codice nativo equivalente alla prima esecuzione. Ad ogni successiva esecuzione, JVM utilizza semplicemente il codice nativo già compilato per ottimizzare le prestazioni.

inserisci qui la descrizione dell'immagine

Senza il compilatore JIT, l'interprete JVM traduce il codice byte riga per riga in modo che appaia come se fosse in esecuzione un'applicazione nativa.

inserisci qui la descrizione dell'immagine

fonte


1
La mia interpretazione di JIT è che si comporta come una memoizzazione, in cui le funzioni utilizzate di frequente vengono "archiviate" e le spese di compilazione dal bytecode java al codice nativo ISA-dipendente vengono escluse. Se questo è corretto, perché java non viene compilato completamente in codice nativo dall'inizio? Ciò ridurrebbe qualsiasi tipo di compilazione di runtime e rendere Java "nativo" per la macchina?
Michael Choi,

12

JIT sta per Just-in-Time, il che significa che il codice viene compilato quando è necessario, non prima del runtime.

Questo è utile perché il compilatore può generare codice ottimizzato per il tuo computer specifico. Un compilatore statico, come il tuo compilatore C medio, compilerà tutto il codice in codice eseguibile sul computer dello sviluppatore. Quindi il compilatore eseguirà ottimizzazioni basate su alcuni presupposti. Può compilare più lentamente e fare più ottimizzazioni perché non sta rallentando l'esecuzione del programma per l'utente.


Perché i codici compilati non sono memorizzati in qualche punto del computer dell'utente, quindi alla successiva esecuzione dell'applicazione JIT non deve ricompilarli di nuovo?
omerfarukdogan,

Buone osservazioni. È possibile farlo, ma se effettivamente è vantaggioso dipende dalla piattaforma e dall'uso dell'app. L'ottimizzazione JIT non è necessariamente la stessa dell'ottimizzazione offline o anticipata, quindi il vantaggio potrebbe essere solo "non JITting", il che potrebbe o potrebbe non essere di grande aiuto.
Brian Lyttle,

9

Dopo che il codice byte (che è neutrale rispetto all'architettura) è stato generato dal compilatore Java, l'esecuzione verrà gestita da JVM (in Java). Il codice byte verrà caricato in JVM dal caricatore e quindi ogni istruzione di byte verrà interpretata.

Quando dobbiamo chiamare un metodo più volte, dobbiamo interpretare lo stesso codice molte volte e ciò potrebbe richiedere più tempo del necessario. Quindi abbiamo i compilatori JIT (just-in-time). Quando il byte è stato caricato in JVM (il suo tempo di esecuzione), l'intero codice verrà compilato anziché interpretato, risparmiando così tempo.

I compilatori JIT funzionano solo durante il runtime, quindi non abbiamo alcun output binario.


2
L'intero codice non viene compilato quando viene caricato nella JVM, poiché ci sono poche informazioni (leggi: guida) su come procedere con la compilazione. Tieni presente che le prestazioni sono l'obiettivo finale. JIT è piuttosto selettivo: monitorare e selezionare i metodi più popolari per l'ottimizzazione. E continua a farlo fino a quando non viene raggiunto il massimo livello di ottimizzazione per i singoli metodi.
Yaw Boakye,

7

Just In Time Compiler (JIT):
compila i bytecode java nelle istruzioni macchina di quella specifica CPU.

Ad esempio, se abbiamo un'istruzione loop nel nostro codice java:

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

Il codice di loop sopra riportato viene eseguito per 10 volte se il valore di i è 0.

Non è necessario compilare il bytecode per 10 volte più e più volte poiché la stessa istruzione verrà eseguita per 10 volte. In tal caso, è necessario compilare quel codice una sola volta e il valore può essere modificato per il numero di volte richiesto. Quindi, il compilatore Just In Time (JIT) tiene traccia di tali istruzioni e metodi (come detto prima) e compila tali pezzi di codice byte in codice macchina per prestazioni migliori.

Un altro esempio simile è che una ricerca di un modello usando "Espressione regolare" in un elenco di stringhe / frasi.

Il compilatore JIT non compila tutto il codice in codice macchina. Compila il codice che ha un modello simile in fase di esecuzione.

Consulta questa documentazione Oracle su Understand JIT per saperne di più.


"Non è necessario compilare il bytecode per 10 volte più e più volte poiché la stessa istruzione verrà eseguita per 10 volte" - che dire di un normale compilatore? Compila questo pezzo più volte?
TT_

4

Hai un codice che è compilato in alcuni IL (linguaggio intermedio). Quando si esegue il programma, il computer non capisce questo codice. Comprende solo il codice nativo. Quindi il compilatore JIT compila il tuo IL in codice nativo al volo. Lo fa a livello di metodo.


2
Cosa intendi con "livello di metodo"?
Koray Tugay,

4

So che questo è un vecchio thread, ma l'ottimizzazione del runtime è un'altra parte importante della compilazione JIT che non sembra essere discussa qui. Fondamentalmente, il compilatore JIT può monitorare il programma mentre viene eseguito per determinare i modi per migliorare l'esecuzione. Quindi, può apportare tali modifiche al volo - durante il runtime. Ottimizzazione di Google JIT (javaworld ha un articolo abbastanza buono a riguardo. )


3

Un compilatore just in time (JIT) è un software che riceve un input non eseguibile e restituisce il codice macchina appropriato da eseguire. Per esempio:

Intermediate representation    JIT    Native machine code for the current CPU architecture

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

La conseguenza di ciò è che per una determinata architettura della CPU deve essere installato il compilatore JIT appropriato.

Compilatore di differenze, interprete e JIT

Sebbene possano esserci eccezioni in generale quando vogliamo trasformare il codice sorgente in codice macchina, possiamo usare:

  1. Compilatore : accetta il codice sorgente e restituisce un eseguibile
  2. Interprete : esegue l'istruzione di programma per istruzione. Prende un segmento eseguibile del codice sorgente e lo trasforma in istruzioni macchina. Questo processo viene ripetuto fino a quando tutto il codice sorgente viene trasformato in istruzioni macchina ed eseguito.
  3. JIT : sono possibili molte diverse implementazioni di una JIT, tuttavia una JIT è generalmente una combinazione di un compilatore e un interprete. Il JIT trasforma prima i dati intermedi (ad es. Bytecode Java) che riceve in linguaggio macchina tramite interpretazione. Un JIT può spesso rilevare quando una determinata parte del codice viene eseguita spesso e compilerà questa parte per un'esecuzione più rapida.

2

Jit sta per just in time compilatore jit è un programma che trasforma il codice byte java in istruzioni che possono essere inviate direttamente al processore.

L'uso del compilatore just in time di java (in realtà un secondo compilatore) su una particolare piattaforma di sistema consente di adattare il bytecode a un particolare codice di sistema, una volta che il codice è stato ricompilato dal compositore jit, di solito verrà eseguito più rapidamente nel computer.

Il compilatore just-in-time viene fornito con la macchina virtuale e viene utilizzato facoltativamente. Compila il bytecode in codice eseguibile specifico della piattaforma che viene immediatamente eseguito.


2

la compilazione just-in-time (JIT), (anche traduzione dinamica o compilazione run-time), è un modo di eseguire il codice del computer che prevede la compilazione durante l'esecuzione di un programma - in fase di esecuzione - piuttosto che prima dell'esecuzione .

La compilazione IT è una combinazione dei due approcci tradizionali alla traduzione in codice macchina - compilazione anticipata (AOT) e interpretazione - e combina alcuni vantaggi e svantaggi di entrambi. La compilazione JIT combina la velocità del codice compilato con la flessibilità dell'interpretazione .

Consideriamo JIT utilizzato in JVM,

Ad esempio, i compilatori JSM JVM HotSpot generano ottimizzazioni dinamiche. In altre parole, prendono decisioni di ottimizzazione mentre l'applicazione Java è in esecuzione e generano istruzioni di macchine native ad alte prestazioni destinate all'architettura di sistema sottostante.

Quando viene scelto un metodo per la compilazione, JVM trasmette il suo bytecode al compilatore Just-In-Time (JIT). È necessario che JIT comprenda la semantica e la sintassi del bytecode prima di poter compilare correttamente il metodo. Per aiutare il compilatore JIT ad analizzare il metodo, i suoi bytecode vengono prima riformulati in una rappresentazione interna chiamata alberi di traccia, che assomiglia più al codice macchina che al bytecode. Analisi e ottimizzazioni vengono quindi eseguite sugli alberi del metodo. Alla fine, gli alberi vengono tradotti in codice nativo.

Un albero di traccia è una struttura di dati che viene utilizzata nella compilazione di runtime del codice di programmazione. Gli alberi di traccia vengono utilizzati in un tipo di compilatore "just in time" che traccia l'esecuzione del codice durante gli hotspot e lo compila. Fare riferimento questo .

Fare riferimento :


1

Un compilatore non JIT prende il codice sorgente e lo trasforma in codice byte specifico della macchina al momento della compilazione. Un compilatore JIT prende il codice byte agnostico della macchina che è stato generato in fase di compilazione e lo trasforma in codice byte specifico della macchina in fase di esecuzione. Il compilatore JIT che Java utilizza è ciò che consente a un singolo binario di essere eseguito su una moltitudine di piattaforme senza modifiche.


0

Il 20% del codice byte viene utilizzato l'80% delle volte. Il compilatore JIT ottiene queste statistiche e ottimizza questo 20% del codice byte per l'esecuzione più veloce aggiungendo metodi inline, rimozione di blocchi inutilizzati ecc. E creando anche il bytecode specifico per quella macchina. Sto citando questo articolo, ho trovato utile. http://java.dzone.com/articles/just-time-compiler-jit-hotspot


Non sono sicuro del motivo per cui questo è stato contrassegnato -1. Penso che il punto qui sia che le statistiche sul tempo di esecuzione vengano utilizzate per ottimizzare.
Eze,

Sì, ma la risposta non l'ha definita così. Letteralmente, JIT non ottimizza il 20% più caldo del codice.
mabraham,

0

JIT si riferisce al motore di esecuzione in alcune implementazioni JVM, una che è più veloce ma richiede più memoria, è un compilatore just-in-time. In questo schema, i bytecode di un metodo vengono compilati in codice macchina nativo la prima volta che viene invocato il metodo. Il codice macchina nativo per il metodo viene quindi memorizzato nella cache, quindi può essere riutilizzato alla successiva chiamata dello stesso metodo.


2
Eviterei di rispondere a una domanda del genere se non fornisci qualcosa di nuovo / migliore. Se ricevi qualche reazione è probabilmente un voto negativo o una critica: la tua risposta è imprecisa. "JIT" non si limita a una Java Virtual Machine , "più veloce ma utilizza più memoria" è un effetto probabile ma non inerente al concetto JIT e spesso i metodi non vengono compilati sulla prima chiamata, piuttosto dopo alcuni quando diventa chiaro che trascorrere del tempo su JIT è complessivamente vantaggioso.
zapl,

0

JVM esegue effettivamente le fasi di compilazione durante il runtime per motivi di prestazioni. Ciò significa che Java non ha una separazione pulita dell'esecuzione della compilazione. Per prima cosa esegue una cosiddetta compilazione statica dal codice sorgente Java al bytecode. Quindi questo bytecode viene passato alla JVM per l'esecuzione. Ma l'esecuzione del bytecode è lenta, quindi la JVM misura la frequenza con cui viene eseguito il bytecode e quando rileva un "hotspot" di codice che viene eseguito molto frequentemente esegue una compilazione dinamica dal bytecode al machinecode del codice "hotspot" (profiler hotspot). Così efficacemente oggi i programmi Java sono eseguiti dall'esecuzione di machinecode.


0

Il compilatore Just In Time noto anche come compilatore JIT viene utilizzato per il miglioramento delle prestazioni in Java. Si è abilitata di default. È una compilazione eseguita in fase di esecuzione piuttosto prima. Java ha reso popolare l'uso del compilatore JIT includendolo in JVM.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.