Il codice Bytecode Java è interpretato? [chiuso]

6

La definizione di interpretazione (correggimi se ho torto) sta analizzando il codice in questo modo:

1 - Traduci la riga attualmente analizzata in una lingua intermedia. 2 - Esegui la riga tradotta. 3 - vai alla riga successiva. 4 - Traduci. 5 - eseguilo. E così via.

In caso affermativo, perché la gente dice che la JVM interpreta il Bytecode Java? Quello che fa è eseguirlo . Il Bytecode è già tradotto nel codice sorgente Java, quindi non è necessario tradurre ulteriormente.

Perché è il termine interpretazione coinvolto?

Se questo termine viene utilizzato perché la JVM esegue il Bytecode riga per riga , direi che qualsiasi esecuzione lo fa. Esegue il codice eseguibile dall'alto verso il basso. Perché utilizzare il termine interpretazione ?

Interpretazione al contrario di cosa?

    
posta NPElover 08.03.2014 - 18:16
fonte

6 risposte

9

Un processore esegue le istruzioni della macchina. Sono l'unica cosa che un processore capisce.

Il bytecode Java è un modo intermedio, compatto, di rappresentare una serie di operazioni (per mancanza di un termine migliore). Il processore non può eseguirli direttamente.

La Java Virtual Machine elabora quel flusso di operazioni bytecode e le interpreta in una serie di istruzioni macchina che il processore deve eseguire.

Questo è un processo molto simile a quello che l'interprete Python esegue su uno script Python di input. Non importa che Java Bytecode sia un formato binario per velocizzare l'esecuzione, e uno script Python è un file di testo. Perfino Python elabora i moduli .py in un modulo binario .pyc per lo stesso motivo. La differenza fondamentale è che il bytecode Java ha attraversato una fase di pre-elaborazione più approfondita, risolvendo le chiamate di metodo sugli oggetti, controllando i tipi ecc., In modo che la JVM non debba eseguirli.

Questo processo VM è ciò che consente a Java compilato di essere trasferibile su qualsiasi computer, sia che esso abbia un processore X86, ARM o qualsiasi altra cosa, purché esista una JVM per quella piattaforma. Le diverse versioni di JVM interpretano tutte lo stesso bytecode, ma producono le istruzioni macchina appropriate per il loro processore.

Per ulteriori dettagli e un'eccellente spiegazione sulla differenza tra una macchina virtuale come Java e un interprete come CPython, vedi la risposta accettata qui:

link

    
risposta data 08.03.2014 - 20:18
fonte
4

The definition of interpretation (correct me if I'm wrong) is parsing code like so:

  1. Translate currently parsed line to some intermediate language.
  2. Run the translated line.
  3. Move to the next line.
  4. Translate it.
  5. Run it. And so on.

Questa non è una definizione valida. Descrive solo un modo di implementare un interprete, ma esclude altri modi. La maggior parte degli interpreti non opera una linea in un momento del genere. È più normale tradurre dal codice sorgente in un modulo intermedio prima di provare effettivamente a eseguire il modulo intermedio.

E anche la frase "forma intermedia" è potenzialmente errata, nel senso che suggerisce che ci sia qualche altra forma per il codice dopo la forma intermedia.

If so, why do people say that the JVM interprets the Java Bytecode? What it does is execute it.

L'interpretazione è una forma di esecuzione. Quindi non c'è contraddizione.

Interpretation as opposed to what?

Diversamente dalla compilazione dei bytecode nel codice nativo e dall'esecuzione del codice nativo. Questo è ciò che tipicamente accade nelle tipiche implementazioni Java ... in un modo o nell'altro.

In una JVM tipica , i bytecode vengono interpretati per iniziare. Dopo un po 'il compilatore JIT li compila in codice nativo che può essere eseguito direttamente. Altre modalità includono:

  • Interpretazione bytecode sempre; per esempio. utilizzando java -int
  • Compilazione in anticipo; per esempio. utilizzando gcj .
  • Caricamento in tempo reale ... in cui i bytecode sono compilati in codice nativo mentre vengono caricati dal classloader; per esempio. JNode fa questo.

QUESTION FOLLOWUP

JIT execution means to compile each line during execution, correct? If so, how is it different than interpretation?

Innanzitutto, non è corretto:

  • Non esiste una cosa come "Esecuzione JIT". Quando la gente dice questo, significa davvero "compilazione ed esecuzione JIT" ... e non lo stanno spiegando.

  • La compilazione JIT non viene eseguita una riga alla volta. In genere viene eseguito un metodo alla volta.

E la differenza sta in ciò che sta facendo. Il compilatore JIT lavora per compilare bytecode su codice nativo. Non esegue i bytecode. L'esecuzione dei bytecode viene eseguita interpretando i bytecode (prima che siano compilati con JIT) o eseguendo il codice nativo che il compilatore JIT ha prodotto.

    
risposta data 09.03.2014 - 04:15
fonte
1

Dipende dall'implementazione.

Il bytecode Java non è la stessa cosa del codice macchina. È un formato molto simile a quello utilizzato dalla maggior parte delle architetture, il che rende relativamente facile la conversione in codice macchina, ma non lo sono consapevole di tutte le macchine che lo eseguono in modo nativo.

Le specifiche Java non si preoccupano di come il codice viene eseguito, a patto che i risultati siano ciò che le specifiche dicono che dovrebbero essere. Ma se non lo stai eseguendo in modo nativo, devi tradurlo in qualche modo. Tu puoi farlo con l'interpretazione, ed è così che funzionavano le prime JVM, ma questa tecnica è andata a vuoto negli ultimi anni. Al giorno d'oggi, è più comune compilarlo in codice nativo , sia in anticipo o just-in-time, e poi eseguirlo al posto del bytecode.

    
risposta data 08.03.2014 - 20:25
fonte
1

Interpretazione : significa che prendi un piccolo pezzo di codice, capisci cosa fa e poi fallo. Il piccolo pezzo di codice può essere codice sorgente "plain text", ma può anche essere una sorta di codice pre-tokenizzato, o una sorta di codice byte, o istruzioni native per una diversa CPU. La differenza importante qui è che per interpretare il suo codice non mai convertito in codice nativo per la CPU su cui è in esecuzione.

Compilazione : ciò significa che converti il codice sorgente in codice nativo. Quando la maggior parte delle persone pensa ai "compilatori", pensano a uno strumento che converte codice sorgente in codice nativo in codice nativo (noto come "compilazione anticipata" perché è compilato prima dell'esecuzione - spesso anche prima che l'utente finale lo riceva), ma questo non è l'unico modo per compilare. Il vantaggio principale della compilazione in anticipo è che il compilatore può dedicare molto tempo all'ottimizzazione del codice molto bene senza che l'utente finale si preoccupi di quanto tempo ci vuole.

Compilazione JIT : questo è uno dei diversi casi di compilazione (nota: JIT è "Just In Time", e diverse persone chiameranno invece questa traduzione dinamica). In questo caso attendi che sia necessario eseguire una piccola parte di codice, quindi compila quel piccolo pezzo in codice nativo ed eseguilo; poi vai alla ricerca del prossimo pezzo di codice. Memorizzando nella cache i piccoli pezzi precedentemente compilati si finisce per compilare la maggior parte del programma mentre il programma è in esecuzione. Per il codice che viene eseguito spesso questo è molto più veloce dell'interpretazione; ma per il codice eseguito solo quando è più lento dell'interpretazione.

Per Java, prima il codice sorgente del testo in chiaro è compilato in byte-code usando un compilatore in anticipo. Questo è dove si verifica un sacco di ottimizzazione. Successivamente, il codice byte viene eseguito da una Java Virtual Machine (JVM).

Vecchie implementazioni di JVM usate per interpretare il codice byte (che era più lento). Le moderne JVM interpretano il codice di byte che non viene eseguito molto spesso (per evitare il sovraccarico di compilazione quando non è giustificato) e inoltre esegue la compilazione JIT per il codice che viene eseguito spesso (per avvicinarsi alla velocità nativa per quelle parti più importanti).

Fondamentalmente (per implementazioni moderne), non è l'uno o l'altro - è "in anticipo" seguito da una combinazione di compilazione interpretata e JIT.

    
risposta data 09.03.2014 - 14:31
fonte
1

The definition of interpretation (correct me if I'm wrong) is parsing code like so:

1- Translate currently parsed line to some intermediate language. 2- Run the translated line. 3- Move to the next line. 4- Translate it. 5- Run it. And so on.

Direi che la tua definizione di "interpretazione" è sbagliata - non c'è (necessariamente) un passaggio di traduzione nell'interpretazione. Quindi dovrebbe essere:

  1. Leggi un blocco di codice
  2. Esegui quel blocco di codice
  3. Leggi il prossimo pezzo di codice
  4. Esegui il blocco successivo
  5. ... continua

Nel caso di un interprete bytecode JVM, un "blocco" è un singolo bytecode. In un linguaggio interpretato più tradizionale, un "chunk" potrebbe essere una linea. Il passaggio "esegui" potrebbe comportare la generazione di alcune IL per il blocco e quindi l'interpretazione di tale IL, nel qual caso hai due interpreti, uno di livello alto che richiama quello inferiore.

    
risposta data 10.03.2014 - 02:43
fonte
0

Il bytecode Java è una lingua. Le lingue non sono interpretate o compilate. Loro sono . Interpretazione e compilazione sono tratti di, beh, l'interprete o il compilatore (duh!), Cioè un'implementazione di quella lingua.

Esistono implementazioni interpretate della JVM (es. versioni iniziali di Sun JVM prima di Java 1.2), ci sono implementazioni compilate della JVM (es. prime versioni di Maxine), ma l'implementazione più comunemente utilizzata, Sun / Oracle HotSpot La JVM è in realtà entrambe le cose: prima interpreta il bytecode, raccoglie statistiche, quindi compila le parti critiche per le prestazioni utilizzando le informazioni di ottimizzazione derivate da tali statistiche.

    
risposta data 08.03.2014 - 20:59
fonte

Leggi altre domande sui tag