Il compilatore JIT

Il compilatore Just - In - Time (JIT) è un componente dell'ambiente di runtime che migliora le prestazioni delle applicazioni Java™ compilando bytecode in codice macchina nativo al runtime.

I programmi Java sono costituiti da classi, che contengono bytecode neutrali alla piattaforma che possono essere interpretati da una JVM su molte architetture di computer differenti. In fase di runtime, la JVM carica i file di classe, determina la semantica di ogni singolo bytecode ed esegue il calcolo appropriato. L'utilizzo aggiuntivo del processore e della memoria durante l'interpretazione indica che un'applicazione Java viene eseguita più lentamente di un'applicazione nativa. Il compilatore JIT consente di migliorare le prestazioni dei programmi Java compilando bytecode nel codice macchina nativo al runtime.

Il compilatore JIT è abilitato per impostazione predefinita. Quando un metodo è stato compilato, la JVM richiama direttamente il codice compilato di tale metodo invece di interpretarlo. In teoria, se la compilazione non richiedesse il tempo del processore e l'utilizzo della memoria, la compilazione di ogni metodo potrebbe consentire alla velocità del programma Java di corrispondere a quella di un'applicazione nativa.

La compilazione JIT richiede tempo del processore e utilizzo della memoria. Quando la JVM viene avviata per la prima volta, vengono chiamati migliaia di metodi. La compilazione di tutti questi metodi può influenzare significativamente il tempo di avvio, anche se il programma alla fine raggiunge prestazioni di picco molto buone.

In pratica, i metodi non vengono compilati la prima volta che vengono richiamati. Per ogni metodo, la JVM conserva un conteggio di richiami, che inizia a un valore di soglia di compilazione predefinito e viene ridotto ogni volta che viene chiamato il metodo. Quando il conteggio delle chiamate raggiunge lo zero, viene attivata una compilazione just - in - time per il metodo. Pertanto, i metodi spesso utilizzati vengono compilati subito dopo l'avvio della JVM e i metodi meno utilizzati vengono compilati molto più tardi o non vengono compilati affatto. La soglia di compilazione JIT consente alla JVM di avviarsi rapidamente e di migliorare le prestazioni. Il valore di soglia è stato selezionato per ottenere un equilibrio ottimale tra tempi di avvio e prestazioni a lungo termine.

Il compilatore JIT può compilare un metodo a diversi livelli di ottimizzazione: cold, warm, hot, veryHoto scorching (consultare optlevel in -Xjit). Livelli di ottimizzazione più elevati dovrebbero fornire prestazioni migliori, ma hanno anche un costo di compilazione più elevato in termini di CPU e memoria. Il livello di ottimizzazione iniziale o predefinito per un metodo è warm, ma a volte l'euristica JIT esegue il downgrade del livello di ottimizzazione a cold per migliorare il tempo di avvio.

Un metodo può essere ricompilato ad un livello di ottimizzazione superiore attraverso meccanismi differenti. Uno di questi meccanismi è il campionamento: il compilatore JIT mantiene un thread di campionamento dedicato che si attiva periodicamente e determina quali metodi Java appaiono più spesso nella parte superiore dello stack. Tali metodi sono considerati più importanti per le prestazioni e sono candidati per essere riottimizzati ai livelli superiori di hot, veryHoto scorching.

È possibile disabilitare il compilatore JIT, nel qual caso verrà interpretato l'intero programma Java. La disabilitazione del compilatore JIT non è consigliata se non per diagnosticare o risolvere i problemi di compilazione JIT.