Java è un linguaggio di programmazione compilato o interpretato?


169

In passato ho usato C ++ come linguaggio di programmazione. So che il codice scritto in C ++ passa attraverso un processo di compilazione fino a diventare codice oggetto "codice macchina".

Vorrei sapere come funziona Java in questo senso. Come viene scritto dall'utente il codice Java eseguito dal computer?


14
Il C ++ potrebbe essere interpretato. Ci sono alcuni interpreti C là fuori.
Tom Hawtin - tackline il

Risposte:


220

Le implementazioni Java in genere utilizzano un processo di compilazione in due passaggi. Il codice sorgente Java viene compilato in bytecode dal compilatore Java. Il bytecode viene eseguito da una Java Virtual Machine (JVM). Le moderne JVM utilizzano una tecnica chiamata compilazione Just-in-Time (JIT) per compilare il bytecode in istruzioni native comprese al volo durante l'esecuzione dalla CPU dell'hardware.

Alcune implementazioni di JVM potrebbero scegliere di interpretare il bytecode anziché JIT compilandolo in codice macchina ed eseguendolo direttamente. Mentre questo è ancora considerato un "interprete", è abbastanza diverso dagli interpreti che leggono ed eseguono il codice sorgente di alto livello (cioè, in questo caso, il codice sorgente Java non viene interpretato direttamente, lo è il bytecode, l'output del compilatore Java.)

È tecnicamente possibile compilare Java in anticipo in codice nativo ed eseguire il binario risultante. È anche possibile interpretare direttamente il codice Java.

Riassumendo, a seconda dell'ambiente di esecuzione, il bytecode può essere:

  • compilato in anticipo ed eseguito come codice nativo (simile alla maggior parte dei compilatori C ++)
  • compilato just-in-time ed eseguito
  • interpretato
  • eseguito direttamente da un processore supportato (bytecode è il set di istruzioni nativo di alcune CPU)

20
In realtà, alcune JVM di HotSpot iniziano interpretando i bytecode e li compila solo in codice nativo dopo aver capito cosa vale la pena compilare e raccolto alcune statistiche su come viene eseguito il codice; ad esempio per capire il percorso più comune intrapreso in ciascun ramo condizionale.
Stephen C,

1
Da qui il termine 'Hotspot' :) Lo fa per ciò che è in esecuzione spesso, per ottenere un'ottimizzazione.
Noon Silk,

4
È possibile disattivare l'interprete in HotSpot con -Xcomp. Vale la pena provare un'applicazione per vedere che brutta idea è.
Tom Hawtin - tackline il

1
C'è un'affermazione "La versione attuale di Sun HotSpot JVM utilizza una tecnica chiamata compilazione Just-in-time (JIT) per compilare il bytecode nelle istruzioni native comprese dalla CPU al volo in fase di esecuzione." Avevo l'impressione che JVM fosse un interprete ma suggerisce che compila ulteriormente il codice byte. Sono confuso. Inoltre è scritto che lo fa al volo in fase di esecuzione. Qualcuno può spiegare anche questo?
Anand,

poiché java è un linguaggio interpretato in che modo influirà sulle prestazioni o sull'esecuzione di qualsiasi applicazione java
NAND

93

inserisci qui la descrizione dell'immagine

Il codice scritto in Java è:

  • Prima compilato in bytecode da un programma chiamato javac come mostrato nella sezione sinistra dell'immagine sopra;
  • Quindi, come mostrato nella sezione destra dell'immagine sopra, un altro programma chiamato java avvia l'ambiente di runtime Java e può compilare e / o interpretare il bytecode utilizzando Java Interpreter / JIT Compiler.

Quando java interpreta il bytecode e quando lo compila? Il codice dell'applicazione viene inizialmente interpretato, ma JVM controlla quali sequenze di bytecode vengono frequentemente eseguite e le traduce in codice macchina per l'esecuzione diretta sull'hardware. Per il bytecode che viene eseguito solo poche volte, questo risparmia il tempo di compilazione e riduce la latenza iniziale; per il bytecode spesso eseguito, la compilazione JIT viene utilizzata per l'esecuzione ad alta velocità, dopo una fase iniziale di interpretazione lenta. Inoltre, poiché un programma impiega la maggior parte del tempo a eseguire una minoranza del suo codice, il tempo di compilazione ridotto è significativo. Infine, durante l'interpretazione iniziale del codice, le statistiche di esecuzione possono essere raccolte prima della compilazione, il che aiuta a eseguire una migliore ottimizzazione.


È a causa del bytecode memorizzato nella cache che Java utilizza molta memoria?
Pedro Gordo,

3
@sedulam: "memoria" è un'affermazione confusa. La gestione della memoria di Java è piuttosto semplice: le tre generazioni sono ciò che JVM utilizza per la creazione e la manutenzione dei suoi oggetti. Questa altra risposta SO può essere utile per te.
displayName

Con la spiegazione sopra, teoricamente, il codice compilato C ++ sarà sempre più veloce del codice java logicamente simile poiché ci sarà sempre una parte del file .class che JIT decide di non trasformare in codice macchina. In altre parole, java non può mai catturare la velocità di esecuzione bare metal che C ++ ha dimostrato. È questo presupposto corretto?
DevdattaK,

@DevdattaK: non conosco molto C ++, ma la mia ipotesi è che per programmi più piccoli e specializzati, Java potrebbe darti il ​​risultato più velocemente perché non perderebbe tempo a compilare quelle porzioni di codice dove non c'è molta velocità disponibile.
displayName

1
@DevdattaK il tuo assunto è discusso in questa pagina wiki en.m.wikipedia.org/wiki/Java_performance?wprov=sfla1 In breve, non è sempre vero.
Sundar Rajan,

57

I termini "linguaggio interpretato" o "linguaggio compilato" non hanno senso, poiché qualsiasi linguaggio di programmazione può essere interpretato e / o compilato.

Per quanto riguarda le implementazioni esistenti di Java, la maggior parte prevede una fase di compilazione per bytecode , quindi comportano la compilazione. Il runtime può anche caricare bytecode in modo dinamico, quindi è sempre necessaria una forma di interprete bytecode. Tale interprete può a sua volta o meno utilizzare la compilazione per codice nativo internamente.

In questi giorni la compilazione just-in-time parziale viene utilizzata per molte lingue che una volta erano considerate "interpretate", ad esempio JavaScript.


5
Inoltre, il motore di esecuzione JavaScript V8 di Google non si limita a eseguire una compilazione just-in-time parziale. E ' sempre compilato in codice nativo, infatti, V8 non ha nemmeno avere un interprete. Ha solo il compilatore (simile a Maxine, ma a differenza di Maxine V8 ha solo un compilatore). Tutti e tre questi esempi (GCJ, Maxine e V8) dimostrano il tuo punto ancora più forte: non esiste un linguaggio interpretato o un linguaggio compilato. Una lingua non è interpretata o compilata. Una lingua è proprio (Questa è in realtà una citazione di Shriram Krishnamurthi).
Jörg W Mittag,

3
Perché stai parlando di JavaScript in una domanda Java?
Koray Tugay,

1
@KorayTugay Proprio come un esempio. Non voglio certo implicare che Java e Javascript abbiano qualcosa in comune oltre alle prime quattro lettere del loro nome.
Starblue,

Almeno una differenza nel linguaggio interpretato e compilato non significherebbe che un binario del linguaggio compilato non può avere il flusso di esecuzione modificato in qualsiasi momento, mentre un linguaggio interpretato è molto obbediente ad alcune delle attuali funzioni delle funzioni? Le librerie in C sono opzioni mentre in altre lingue non è possibile avere un oggetto array senza un'estensione binaria C che può essere aggiornata o essere codice completamente diverso su un'altra piattaforma. Il linguaggio di scripting sarà in grado di funzionare su entrambi mentre il linguaggio compilato avrebbe bisogno di un binario diverso per essere eseguito
Eaton Emmerich

53

Java viene compilato in bytecode, che quindi va nella Java VM, che lo interpreta.


33
... ma non rigorosamente preciso.
Stephen C,

2
JVM potrebbe scegliere di non "interpretare" il bytecode. Può compilare JIT ed eseguirlo direttamente.
Mehrdad Afshari,

1
JIT non lo esegue tecnicamente direttamente. Sta solo ricordando come è stato eseguito.
cletus,

Mehrdad: D'accordo, non ho descritto le possibili operazioni della JIT qui, visto che lo considero fino alla JVM, e comunque stavo mantenendo la mia risposta semplice :)
Noon Silk,

7
cletus: dopo JIT, verrà eseguito direttamente. JIT sta leggendo un pezzo di bytecode (ad esempio un metodo completo ) e sta compilando il codice macchina e saltando su di esso.
Mehrdad Afshari,

12

Java è un linguaggio di programmazione compilato, ma anziché essere compilato direttamente in un codice macchina eseguibile, viene compilato in un modulo binario intermedio chiamato codice byte JVM. Il codice byte viene quindi compilato e / o interpretato per eseguire il programma.


11

Tipo di entrambi. In primo luogo java compilato (alcuni preferirebbero dire "tradotto") in bytecode, che poi compilato o interpretato a seconda dell'umore di JIT.


32
Questo è un software avanzato per sviluppare stati d'animo :)
Thorarin,

5
Il JIT è davvero un software molto sofisticato, che può fare ottimizzazioni basate su informazioni di runtime (come un profiler), che un compilatore in anticipo non può fare (perché non ha informazioni sul comportamento di runtime di un programma in anticipo). Ma probabilmente non ha proprio uno stato d'animo ... :-)
Jesper

5

Java esegue sia la compilazione che l'interpretazione,

In Java, i programmi non vengono compilati in file eseguibili ; sono compilati in bytecode (come discusso in precedenza), che la JVM (Java Virtual Machine) interpreta / esegue in fase di esecuzione. Il codice sorgente Java viene compilato in bytecode quando utilizziamo il compilatore javac. Il bytecode viene salvato sul disco con l'estensione .class .

Quando il programma deve essere eseguito, il bytecode viene convertito, il bytecode può essere convertito, usando il compilatore just-in-time (JIT). Il risultato è il codice macchina che viene quindi immesso nella memoria e viene eseguito.

Javac è il compilatore Java che compila il codice Java in Bytecode. JVM è una macchina virtuale Java che esegue / interpreta / traduce il bytecode in codice nativo della macchina. In Java sebbene sia considerato come un linguaggio interpretato, può usare la compilazione JIT (Just-in-Time) quando il bytecode è nella JVM. Il compilatore JIT legge i bytecode in molte sezioni (o completamente, raramente) e li compila dinamicamente in codice macchina in modo che il programma possa essere eseguito più velocemente, quindi memorizzato nella cache e riutilizzato in seguito senza dover essere ricompilato. Quindi la compilazione JIT combina la velocità del codice compilato con la flessibilità dell'interpretazione.

Un linguaggio interpretato è un tipo di linguaggio di programmazione per il quale la maggior parte delle sue implementazioni esegue istruzioni direttamente e liberamente, senza aver precedentemente compilato un programma in istruzioni in linguaggio macchina. L'interprete esegue direttamente il programma, traducendo ogni istruzione in una sequenza di una o più subroutine già compilate nel codice macchina.

Un linguaggio compilato è un linguaggio di programmazione le cui implementazioni sono in genere compilatori (traduttori che generano codice macchina dal codice sorgente) e non interpreti (esecutori passo-passo del codice sorgente, in cui non avviene alcuna traduzione pre-runtime)

Nelle moderne implementazioni del linguaggio di programmazione come in Java, è sempre più popolare per una piattaforma fornire entrambe le opzioni.


Dovrebbe essere "il bytecode può essere convertito" piuttosto che " viene convertito". Le specifiche Java definiscono il bytecode. Se quel bytecode viene eseguito (a) direttamente nell'hardware , (b) attraverso un interprete, (c) compilato in anticipo o (d) parzialmente compilato al volo in fase di esecuzione, vengono lasciati tutti come dettagli di implementazione. Si noti che tutte e quattro queste opzioni sono state effettivamente utilizzate da varie implementazioni Java nel mondo reale.
Basil Bourque,

Grazie per averlo segnalato. Quindi cosa succede se il bytecode non viene convertito in codice macchina? Mi viene in mente uno scenario in cui il bytecode è l'istruzione nativa impostata per alcuni processori e quindi non è necessaria una conversione. Oppure mi sfugge qualcosa.
prime

Fare clic sul collegamento fornito per la tecnologia Jazelle DBX (Direct Bytecode eXecution) , in cui un sottoinsieme del bytecode JVM è costituito dalle istruzioni della macchina nativa della CPU (kinda-sorta). Senza questo, ottieni il codice macchina generato dal bytecode (a) dall'interprete (al volo), (b) dal compilatore in anticipo, o (c) al volo con un compilatore just-in-time ( interpretato inizialmente, quindi a volte compilato e memorizzato nella cache durante l'esecuzione).
Basil Bourque,

-2

Java è un linguaggio compilato in byte destinato a una piattaforma chiamata Java Virtual Machine che è basata su stack e ha implementazioni molto veloci su molte piattaforme.


1
Cosa significa "byte compilato"?
Jesper,

2
@Jesper: "Byte-compilato" di solito significa "compilato in bytecode". "Bytecode" è un termine generale che copre qualsiasi tipo di codice intermedio non testuale (generalmente non eseguibile dalla macchina).
Greg Hewgill,

-3

Citazione da: https://blogs.oracle.com/ask-arun/entry/run_your_java_applications_faster

Gli sviluppatori di applicazioni possono sviluppare il codice dell'applicazione su uno dei vari sistemi operativi disponibili oggi sul mercato. Il linguaggio Java è agnostico in questa fase per il sistema operativo. Il brillante codice sorgente scritto dallo sviluppatore dell'applicazione Java ora viene compilato nel codice Byte Java che nella terminologia Java viene definito compilazione lato client. Questa raccolta in codice byte Java è ciò che consente agli sviluppatori Java di "scrivere una volta". Il codice byte Java può essere eseguito su qualsiasi sistema operativo e server compatibile, rendendo quindi il codice sorgente indipendente dal sistema operativo / server. Dopo la creazione del codice Byte Java Byte, l'interazione tra l'applicazione Java e il SO / Server sottostante è più intima. Il viaggio continua: il framework delle applicazioni enterprise esegue questi codici byte Java in un ambiente di runtime noto come Java Virtual Machine (JVM) o Java Runtime Environment (JRE). JVM ha stretti legami con il sistema operativo e l'hardware sottostanti perché sfrutta le risorse offerte dal sistema operativo e dal server. Il codice byte Java ora è compilato in un codice eseguibile in linguaggio macchina specifico per la piattaforma. Questa viene definita compilazione lato server.

Quindi direi che Java è sicuramente un linguaggio compilato.

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.