2013-08-13 8 views
6

Recentemente ho partecipato a una discussione sull'efficienza di Java. Come ho ascoltato, molti argomenti contro Java erano che l'interpretazione è "molto dispendiosa in termini di tempo" e per questo anche i semplici programmi Java sono molto più lenti di quelli simili compilati direttamente sul codice macchina.Compilazione just-in-time - quando avviene effettivamente in Java?

Una risposta a ciò era che il codice Java viene spesso compilato direttamente sul codice macchina, se solo JVM calcola rende il programma più veloce di se fosse interpretato in un modo standard.

Le mie domande sono: quando JVM "decide" effettivamente di eseguire la compilazione just-in-time? Quali sono i criteri che rendono JIT più efficiente dell'interpretazione bytecode standard? Voglio dire, la compilazione richiede un po 'di tempo e, per quanto ho capito, tutto dovrebbe succedere quando il programma è già in esecuzione?

+0

Riferimento: [Compilazione JIT] (http://en.wikipedia.org/wiki/Just-in-time_compilation) – Coffee

risposta

10

Questo varia ampiamente a seconda della JVM e delle sue impostazioni. Wikipedia:

Ad esempio, la Java Virtual Machine di Sun ha due modalità principali: client e server. In modalità client, viene eseguita una compilazione e ottimizzazione minime, per ridurre i tempi di avvio. In modalità server, viene eseguita un'ampia compilazione e ottimizzazione, per massimizzare le prestazioni una volta che l'applicazione è in esecuzione, sacrificando il tempo di avvio. Altri compilatori Java just-in-time hanno utilizzato una misurazione runtime del numero di volte che un metodo ha eseguito combinato con la dimensione bytecode di un metodo come euristica per decidere quando compilare. [4] Ancora un altro usa il numero di volte eseguito combinato con il rilevamento dei loop [5].

Un'approssimazione grossolana per una vaniglia JVM HotSpot in modalità -server è che JIT si verifica quando la JVM nota che un certo metodo è stato chiamato un sacco, solitamente più di un numero specifico di volte. (Questo è il motivo per cui la JVM è chiamata "HotSpot" - perché identifica e ottimizza "punti caldi" nel codice.) A questo punto, la JVM conosce alcune cose:

  • Si sa che questo metodo è vale la pena spendere il tempo per ottimizzare, perché, beh, viene chiamato molto.
  • Si sa molto circa le caratteristiche del mondo reale di questa funzione:
    • se un ramo di un if affermazione è molto più comune di un altro, in modo che possa migliorare branch prediction
    • se per esempio un List passato a questo metodo è di solito un ArrayList, quindi può fare ottimizzazioni e inlinings per il caso specifico di un ArrayList.

Si noti che se si è compilato in anticipo in codice macchina, non si avrebbe un sacco di queste informazioni per ottimizzare con - il compilatore non sa in anticipo quali percorsi tendono ad essere più comune di altri. Ma se aspetti di fare l'ottimizzazione fino a quando non disponi di dati reali, puoi prendere decisioni di ottimizzazione migliori.

Altri dettagli su cosa fa il JIT sono here.

+0

+1 per "un certo metodo è stato chiamato molto" ... "Sa che questo il metodo viene chiamato molto ":) Ma seriamente, buona risposta. –

+0

Non sono sicuro di averlo capito bene, ma la JVM saprà solo che un metodo viene chiamato spesso dopo che è già stato chiamato più volte. Intendo dire che la JVM interpreta bytecode "on-line", non "sa" quante volte verrà richiamato un metodo, giusto? Oppure il compilatore aggiunge tali informazioni al bytecode al momento della compilazione? In caso contrario, ci sarebbe sempre la possibilità che questo metodo sia stato chiamato molto all'inizio del programma, e in seguito non è utilizzato - in tal caso, se JVM eseguisse JIT con tale metodo, sarebbe semplicemente perdere tempo (o molti) di tempo, se il metodo era grande di per sé). – 3yakuya

+0

No, certo che non lo sa in anticipo; suppone che se un metodo è stato chiamato molto prima, continuerà ad essere chiamato lotti. Ma questo è un assunto perfettamente valido nella pratica. –

Problemi correlati