Ist Java eine kompilierte oder eine interpretierte Programmiersprache?


168

In der Vergangenheit habe ich C ++ als Programmiersprache verwendet. Ich weiß, dass der in C ++ geschriebene Code einen Kompilierungsprozess durchläuft, bis er zum Objektcode "Maschinencode" wird.

Ich würde gerne wissen, wie Java in dieser Hinsicht funktioniert. Wie wird der vom Benutzer geschriebene Java-Code vom Computer ausgeführt?


14
C ++ könnte interpretiert werden. Es gibt ein paar C-Interpreter da draußen.
Tom Hawtin - Tackline

Antworten:


219

Java-Implementierungen verwenden normalerweise einen zweistufigen Kompilierungsprozess. Java-Quellcode wird vom Java-Compiler zu Bytecode kompiliert. Der Bytecode wird von einer Java Virtual Machine (JVM) ausgeführt. Moderne JVMs verwenden eine Technik namens Just-in-Time (JIT) -Kompilierung , um den Bytecode zu nativen Anweisungen zu kompilieren, die von der Hardware-CPU zur Laufzeit im laufenden Betrieb verstanden werden.

Einige Implementierungen von JVM entscheiden sich möglicherweise dafür, den Bytecode zu interpretieren, anstatt ihn mit JIT zu Maschinencode zu kompilieren und direkt auszuführen. Dies wird zwar immer noch als "Interpreter" betrachtet, unterscheidet sich jedoch erheblich von Interpreten, die den Quellcode auf hoher Ebene lesen und ausführen (dh in diesem Fall wird der Java-Quellcode nicht direkt interpretiert, sondern der Bytecode, der vom Java-Compiler ausgegeben wird).

Es ist technisch möglich, Java vorab zu nativem Code zu kompilieren und die resultierende Binärdatei auszuführen. Es ist auch möglich, den Java-Code direkt zu interpretieren.

Zusammenfassend kann der Bytecode je nach Ausführungsumgebung wie folgt lauten:

  • vorab kompiliert und als nativer Code ausgeführt (ähnlich den meisten C ++ - Compilern)
  • just-in-time kompiliert und ausgeführt
  • interpretiert
  • direkt von einem unterstützten Prozessor ausgeführt (Bytecode ist der native Befehlssatz einiger CPUs)

20
Tatsächlich interpretieren einige HotSpot-JVMs zunächst Bytecodes und kompilieren sie erst zu nativem Code, nachdem sie herausgefunden haben, was es wert ist, kompiliert zu werden, und einige Statistiken darüber gesammelt haben, wie der Code ausgeführt wird. zB um den häufigsten Weg herauszufinden, der in jedem bedingten Zweig genommen wird.
Stephen C

1
Daher der Begriff 'Hotspot' :) Er macht es mit dem, was oft läuft, um eine Optimierung zu erreichen.
Mittag Seide

4
Sie können den Interpreter in HotSpot mit -Xcomp ausschalten. Es lohnt sich, eine Anwendung auszuprobieren, um zu sehen, was für eine schlechte Idee das ist.
Tom Hawtin - Tackline

1
Es gibt eine Aussage: "Die aktuelle Version von Sun HotSpot JVM verwendet eine Technik namens Just-in-Time (JIT) -Kompilierung, um den Bytecode nach den nativen Anweisungen zu kompilieren, die die CPU zur Laufzeit im laufenden Betrieb versteht." Ich hatte den Eindruck, dass JVM ein Interpreter ist, aber es deutet darauf hin, dass es den Bytecode weiter kompiliert. Ich bin verwirrt. Es steht auch geschrieben, dass es dies zur Laufzeit im laufenden Betrieb tut. Kann das auch jemand erklären?
Anand

Da Java eine interpretierte Sprache ist, wie wird sich dies auf die Leistung oder die Ausführung einer Java-Anwendung auswirken
NAND

92

Geben Sie hier die Bildbeschreibung ein

In Java geschriebener Code lautet:

  • Zuerst von einem Programm namens javac zu Bytecode kompiliert , wie im linken Abschnitt des obigen Bildes gezeigt;
  • Wie im rechten Abschnitt des obigen Bildes gezeigt, startet dann ein anderes Programm namens Java die Java-Laufzeitumgebung und kann den Bytecode mithilfe des Java Interpreter / JIT Compiler kompilieren und / oder interpretieren .

Wann interpretiert Java den Bytecode und wann kompiliert er ihn? Der Anwendungscode wird anfänglich interpretiert, aber die JVM überwacht, welche Sequenzen von Bytecode häufig ausgeführt werden, und übersetzt sie zur direkten Ausführung auf der Hardware in Maschinencode. Bei Bytecode, der nur einige Male ausgeführt wird, wird die Kompilierungszeit gespart und die anfängliche Latenz verringert. Für häufig ausgeführten Bytecode wird die JIT-Kompilierung verwendet, um nach einer anfänglichen Phase langsamer Interpretation mit hoher Geschwindigkeit ausgeführt zu werden. Da ein Programm die meiste Zeit damit verbringt, eine Minderheit seines Codes auszuführen, ist außerdem die reduzierte Kompilierungszeit erheblich. Schließlich können während der anfänglichen Code-Interpretation Ausführungsstatistiken vor der Kompilierung gesammelt werden, was zu einer besseren Optimierung beiträgt.


Liegt es an dem zwischengespeicherten Bytecode, dass Java viel Speicher benötigt?
Pedro Gordo

3
@sedulam: "Viel Speicher" ist eine unscharfe Aussage. Die Speicherverwaltung in Java ist recht unkompliziert. Die drei Generationen werden von der JVM für die Erstellung und Wartung ihrer Objekte verwendet. Diese andere SO-Antwort kann für Sie nützlich sein.
DisplayName

Mit der obigen Erklärung sollte C ++ - kompilierter Code theoretisch immer schneller sein als logisch ähnlicher Java-Code, da es immer einen Teil der .class-Datei gibt, den JIT nicht in Maschinencode umwandelt. Mit anderen Worten, Java kann niemals die von C ++ demonstrierte Bare-Metal-Ausführungsgeschwindigkeit erreichen. Ist das die richtige Annahme?
DevdattaK

@ DevdattaK: Ich kenne C ++ nicht so gut, aber ich vermute, dass Java bei kleineren und spezialisierten Programmen das Ergebnis möglicherweise schneller liefert, da es keine Zeit damit verschwenden würde, Teile des Codes zu kompilieren, für die nicht viel Geschwindigkeit verfügbar ist.
DisplayName

1
@DevdattaK Ihre Annahme wird auf dieser Wiki-Seite en.m.wikipedia.org/wiki/Java_performance?wprov=sfla1 diskutiert. Kurz gesagt, es ist nicht immer wahr.
Sundar Rajan

57

Die Begriffe "interpretierte Sprache" oder "kompilierte Sprache" sind nicht sinnvoll, da jede Programmiersprache interpretiert und / oder kompiliert werden kann.

Bei den vorhandenen Implementierungen von Java handelt es sich bei den meisten um einen Kompilierungsschritt zum Bytecode , also um eine Kompilierung. Die Laufzeit kann Bytecode auch dynamisch laden, sodass immer eine Form eines Bytecode-Interpreters benötigt wird. Dieser Interpreter kann wiederum die Kompilierung für nativen Code intern verwenden oder nicht.

Heutzutage wird die teilweise Just-in-Time-Kompilierung für viele Sprachen verwendet, die früher als "interpretiert" galten, beispielsweise JavaScript.


5
Die V8 JavaScript Execution Engine von Google führt nicht nur eine teilweise Just-in-Time-Kompilierung durch. Es immer kompiliert nativen Code, in der Tat, V8 nicht einmal hat einen Dolmetscher. Es hat nur den Compiler (ähnlich wie Maxine, aber im Gegensatz zu Maxine hat V8 nur einen Compiler). Alle drei Beispiele (GCJ, Maxine und V8) beweisen Ihren Standpunkt noch deutlicher: Es gibt keine interpretierte oder kompilierte Sprache. Eine Sprache wird nicht interpretiert oder kompiliert. Eine Sprache , gerade ist (Das ist eigentlich ein Zitat von Shriram Krishnamurthi).
Jörg W Mittag

3
Warum sprichst du in einer Java-Frage über Javascript?
Koray Tugay

1
@KorayTugay Nur als Beispiel. Ich möchte sicher nicht implizieren, dass Java und Javascript etwas gemeinsam haben, außer den ersten vier Buchstaben ihres Namens.
Starblue

Würde zumindest ein Unterschied in der interpretierten und kompilierten Sprache nicht bedeuten, dass der Ausführungsfluss einer kompilierten Sprachbinärdatei zu keinem Zeitpunkt geändert werden kann, während eine interpretierte Sprache einigen der aktuellen Funktionsweisen von Funktionen sehr gehorsam ist? Bibliotheken in C sind eine Option, während Sie in anderen Sprachen kein Array-Objekt ohne eine C-Binärerweiterung haben können, die aktualisiert werden kann oder auf einer anderen Plattform völlig anderen Code enthält. Die Skriptsprache kann auf beiden ausgeführt werden, während für die kompilierte Sprache eine andere Binärdatei erforderlich ist
Eaton Emmerich,

53

Java wird zu Bytecode kompiliert, der dann in die Java-VM gelangt, die ihn interpretiert.


33
... aber nicht genau genug.
Stephen C

2
JVM kann sich dafür entscheiden, den Bytecode nicht zu "interpretieren". Es kann JIT kompilieren und direkt ausführen.
Mehrdad Afshari

1
JIT führt es technisch nicht direkt aus. Es erinnert sich nur daran, wie es ausgeführt wurde.
Cletus

Mehrdad: Einverstanden, ich habe die möglichen JIT-Operationen hier nicht beschrieben, da ich das bis zur JVM betrachte, und ich habe meine Antwort trotzdem einfach gehalten :)
Noon Silk

7
cletus: Nach JIT wird es direkt ausgeführt. JIT liest ein Stück Bytecode (z. B. eine vollständige Methode) und kompiliert es zu Maschinencode und springt dorthin.
Mehrdad Afshari

12

Java ist eine kompilierte Programmiersprache, aber anstatt direkt in ausführbaren Maschinencode zu kompilieren, wird es in eine binäre Zwischenform kompiliert, die als JVM-Bytecode bezeichnet wird. Der Bytecode wird dann kompiliert und / oder interpretiert, um das Programm auszuführen.


11

Art von beidem. Zuerst Java kompiliert (einige würden lieber "übersetzt" sagen) zu Bytecode, der dann entweder kompiliert oder je nach Stimmung der JIT interpretiert wird.


32
Das ist eine fortgeschrittene Software, um Stimmungen entwickelt zu haben :)
Thorarin

5
Die JIT ist in der Tat eine sehr ausgefeilte Software, die Optimierungen basierend auf Laufzeitinformationen (wie einem Profiler) durchführen kann, was ein früherer Compiler nicht kann (weil er keine Informationen zum Laufzeitverhalten von hat ein Programm vorzeitig). Aber es hat wahrscheinlich nicht wirklich Stimmungen ... :-)
Jesper

5

Java kompiliert und interpretiert sowohl.

In Java werden Programme nicht in ausführbare Dateien kompiliert . Sie werden in Bytecode kompiliert (wie bereits erläutert), den die JVM (Java Virtual Machine) zur Laufzeit interpretiert / ausführt. Java-Quellcode wird in Bytecode kompiliert, wenn wir den Javac-Compiler verwenden. Der Bytecode wird mit der Dateierweiterung .class auf der Festplatte gespeichert .

Wenn das Programm ausgeführt werden soll, wird der Bytecode konvertiert. Der Bytecode kann mithilfe des Just-in-Time-Compilers (JIT) konvertiert werden. Das Ergebnis ist Maschinencode, der dann dem Speicher zugeführt und ausgeführt wird.

Javac ist der Java-Compiler, der Java-Code in Bytecode kompiliert. JVM ist eine virtuelle Java-Maschine, die Bytecode ausführt / interpretiert / in nativen Maschinencode übersetzt. In Java wird es zwar als interpretierte Sprache betrachtet, es kann jedoch die JIT-Kompilierung (Just-in-Time) verwenden, wenn sich der Bytecode in der JVM befindet. Der JIT-Compiler liest die Bytecodes in vielen Abschnitten (oder vollständig, selten) und kompiliert sie dynamisch in Maschinencode, damit das Programm schneller ausgeführt und später zwischengespeichert und wiederverwendet werden kann, ohne dass sie neu kompiliert werden müssen. Die JIT-Kompilierung kombiniert also die Geschwindigkeit des kompilierten Codes mit der Flexibilität der Interpretation.

Eine interpretierte Sprache ist eine Art Programmiersprache, für die die meisten ihrer Implementierungen Anweisungen direkt und frei ausführen, ohne zuvor ein Programm in maschinensprachliche Anweisungen zu kompilieren. Der Interpreter führt das Programm direkt aus und übersetzt jede Anweisung in eine Folge von einer oder mehreren Subroutinen, die bereits in Maschinencode kompiliert wurden.

Eine kompilierte Sprache ist eine Programmiersprache, deren Implementierungen in der Regel Compiler (Übersetzer, die Maschinencode aus dem Quellcode generieren) und keine Interpreter sind (schrittweise Ausführen von Quellcode, bei denen keine Übersetzung vor der Laufzeit stattfindet).

In modernen Programmiersprachenimplementierungen wie in Java wird es für eine Plattform immer beliebter, beide Optionen bereitzustellen.


Sollte sein "der Bytecode kann konvertiert werden" anstatt " wird konvertiert". Die Java-Spezifikationen definieren den Bytecode. Ob dieser Bytecode (a) direkt in der Hardware ausgeführt wird , (b) über einen Interpreter, (c) zuvor kompiliert oder (d) zur Laufzeit teilweise im laufenden Betrieb kompiliert wird, bleibt als Implementierungsdetails erhalten. Beachten Sie, dass alle vier dieser Optionen tatsächlich von verschiedenen realen Java-Implementierungen verwendet wurden.
Basil Bourque

Vielen Dank für den Hinweis. Was passiert also, wenn der Bytecode nicht in Maschinencode konvertiert wird? Ich kann mir ein Szenario vorstellen, in dem der Bytecode der native Befehlssatz für einige Prozessoren ist und dann keine Konvertierung erforderlich ist. Oder fehlt mir etwas?
Prime

Klicken Sie auf den Link, den ich für die Jazelle DBX- Technologie (Direct Bytecode eXecution) angegeben habe. Dabei handelt es sich bei einer Teilmenge des JVM-Bytecodes um die nativen Maschinenanweisungen der CPU (irgendwie sorta). Ohne dies erhalten Sie Maschinencode, der aus Bytecode (a) vom Interpreter (im laufenden Betrieb), (b) vom Compiler im Voraus oder (c) im laufenden Betrieb mit einem Just-in-Time-Compiler ( zuerst interpretiert und dann manchmal während der Ausführung kompiliert und zwischengespeichert).
Basil Bourque

-2

Java ist eine bytekompilierte Sprache für eine Plattform namens Java Virtual Machine, die stapelbasiert ist und auf vielen Plattformen einige sehr schnelle Implementierungen aufweist.


1
Was bedeutet "bytekompiliert"?
Jesper

2
@Jesper: "Byte-kompiliert" bedeutet normalerweise "In Bytecode kompiliert". "Bytecode" ist ein allgemeiner Begriff, der jede Art von nicht-textuellem Zwischencode abdeckt (im Allgemeinen nicht maschinenausführbar).
Greg Hewgill

-3

Zitat von: https://blogs.oracle.com/ask-arun/entry/run_your_java_applications_faster

Anwendungsentwickler können den Anwendungscode auf jedem der verschiedenen Betriebssysteme entwickeln, die heute auf dem Markt verfügbar sind. Die Java-Sprache ist zu diesem Zeitpunkt für das Betriebssystem agnostisch. Der vom Java-Anwendungsentwickler geschriebene brillante Quellcode wird jetzt zu Java-Byte-Code kompiliert, der in der Java-Terminologie als clientseitige Kompilierung bezeichnet wird. Diese Kompilierung zu Java-Byte-Code ermöglicht es Java-Entwicklern, einmal zu schreiben. Java-Byte-Code kann auf jedem kompatiblen Betriebssystem und Server ausgeführt werden, wodurch der Quellcode von OS / Server unabhängig wird. Nach der Erstellung des Java-Byte-Codes ist die Interaktion zwischen der Java-Anwendung und dem zugrunde liegenden Betriebssystem / Server enger. Die Reise geht weiter - Das Enterprise Applications Framework führt diese Java-Byte-Codes in einer Laufzeitumgebung aus, die als Java Virtual Machine (JVM) oder Java Runtime Environment (JRE) bezeichnet wird. Die JVM ist eng mit dem zugrunde liegenden Betriebssystem und der zugrunde liegenden Hardware verbunden, da sie die vom Betriebssystem und vom Server angebotenen Ressourcen nutzt. Java-Byte-Code wird jetzt zu einem plattformspezifischen ausführbaren Code in Maschinensprache kompiliert. Dies wird als serverseitige Kompilierung bezeichnet.

Ich würde also sagen, Java ist definitiv eine kompilierte Sprache.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.