Java est-il un langage de programmation compilé ou interprété?

169

Dans le passé, j'ai utilisé C ++ comme langage de programmation. Je sais que le code écrit en C ++ passe par un processus de compilation jusqu'à ce qu'il devienne un code objet "code machine".

J'aimerais savoir comment Java fonctionne à cet égard. Comment l'utilisateur écrit-il le code Java exécuté par l'ordinateur?

Afficher un nom
la source
14
C ++ pourrait être interprété. Il existe quelques interprètes C là-bas.
Tom Hawtin - tackline

Réponses:

220

Les implémentations Java utilisent généralement un processus de compilation en deux étapes. Le code source Java est compilé en bytecode par le compilateur Java. Le bytecode est exécuté par une machine virtuelle Java (JVM). Les JVM modernes utilisent une technique appelée compilation Just-in-Time (JIT) pour compiler le bytecode en instructions natives comprises par le processeur matériel à la volée au moment de l'exécution.

Certaines implémentations de JVM peuvent choisir d'interpréter le bytecode au lieu de le compiler JIT en code machine et de l'exécuter directement. Bien que cela soit toujours considéré comme un «interpréteur», il est assez différent des interpréteurs qui lisent et exécutent le code source de haut niveau (c'est-à-dire dans ce cas, le code source Java n'est pas interprété directement, le bytecode, la sortie du compilateur Java, l'est.)

Il est techniquement possible de compiler Java en code natif à l'avance et d'exécuter le binaire résultant. Il est également possible d'interpréter directement le code Java.

Pour résumer, selon l'environnement d'exécution, le bytecode peut être:

  • compilé à l'avance et exécuté en tant que code natif (similaire à la plupart des compilateurs C ++)
  • compilé juste à temps et exécuté
  • interprété
  • directement exécuté par un processeur pris en charge (le bytecode est le jeu d'instructions natif de certains processeurs)
Mehrdad Afshari
la source
20
En fait, certaines JVM HotSpot commencent par interpréter les bytecodes, et ne les compile en code natif qu'après avoir compris ce qui vaut la peine d'être compilé et rassemblé des statistiques sur la manière dont le code est exécuté; par exemple, pour déterminer le chemin le plus courant emprunté dans chaque branche conditionnelle.
Stephen C
1
D'où le terme 'Hotspot' :) Il le fait à ce qui tourne souvent, pour obtenir une optimisation.
Noon Silk
4
Vous pouvez désactiver l'interpréteur dans HotSpot avec -Xcomp. Cela vaut la peine d'essayer une application pour voir à quel point c'est une mauvaise idée.
Tom Hawtin - tackline
1
Il y a une déclaration "La version actuelle de Sun HotSpot JVM utilise une technique appelée compilation juste à temps (JIT) pour compiler le bytecode aux instructions natives comprises par le CPU à la volée au moment de l'exécution." J'avais l'impression que JVM est un interpréteur, mais cela suggère qu'il compile davantage le code d'octet. Je suis confus. Il est également écrit qu'il le fait à la volée au moment de l'exécution. Quelqu'un peut-il expliquer cela aussi?
Anand
puisque java est un langage interprété, comment cela affectera-t-il les performances ou l'exécution de toute application java
NAND
94

entrez la description de l'image ici

Le code écrit en Java est:

  • D'abord compilé en bytecode par un programme appelé javac comme indiqué dans la section gauche de l'image ci-dessus;
  • Ensuite, comme indiqué dans la section de droite de l'image ci-dessus, un autre programme appelé java démarre l'environnement d'exécution Java et il peut compiler et / ou interpréter le bytecode à l'aide de l'interpréteur Java / compilateur JIT.

Quand Java interprète-t-il le bytecode et quand le compile-t-il? Le code de l'application est initialement interprété, mais la JVM surveille les séquences de bytecode fréquemment exécutées et les traduit en code machine pour une exécution directe sur le matériel. Pour le bytecode qui n'est exécuté que quelques fois, cela économise le temps de compilation et réduit la latence initiale; pour le bytecode fréquemment exécuté, la compilation JIT est utilisée pour s'exécuter à grande vitesse, après une phase initiale d'interprétation lente. De plus, comme un programme passe le plus de temps à exécuter une minorité de son code, le temps de compilation réduit est significatif. Enfin, lors de l'interprétation initiale du code, les statistiques d'exécution peuvent être collectées avant la compilation, ce qui permet une meilleure optimisation.

Afficher un nom
la source
Est-ce à cause du bytecode mis en cache que Java utilise beaucoup de mémoire?
Pedro Gordo
3
@sedulam: «Beaucoup de mémoire» est une déclaration floue. La gestion de la mémoire Java est assez simple - Les trois générations sont ce que la JVM utilise pour la création et la maintenance de ses objets. Cette autre réponse SO peut vous être utile.
displayName
Avec l'explication ci-dessus, théoriquement, le code compilé C ++ sera toujours plus rapide que le code java logiquement similaire car il y aura toujours une partie du fichier .class que JIT décide de ne pas transformer en code machine. En d'autres termes, java ne peut jamais attraper la vitesse d'exécution du bare metal démontrée par C ++. Cette hypothèse est-elle correcte?
DevdattaK
@DevdattaK: Je ne connais pas beaucoup le C ++ mais je suppose que pour les programmes plus petits et spécialisés, Java peut vous donner le résultat plus rapidement car il ne perdrait pas de temps à compiler ces parties de code où il n'y a pas beaucoup de vitesse disponible.
displayName
1
@DevdattaK votre hypothèse est discutée dans cette page wiki en.m.wikipedia.org/wiki/Java_performance?wprov=sfla1 En bref, ce n'est pas toujours vrai.
Sundar Rajan
59

Les termes «langage interprété» ou «langage compilé» n'ont aucun sens, car n'importe quel langage de programmation peut être interprété et / ou compilé.

Quant aux implémentations existantes de Java, la plupart impliquent une étape de compilation en bytecode , donc elles impliquent une compilation. Le runtime peut également charger dynamiquement le bytecode, donc une forme d'interpréteur de bytecode est toujours nécessaire. Cet interpréteur peut ou non utiliser à son tour la compilation en code natif en interne.

De nos jours, la compilation partielle juste à temps est utilisée pour de nombreux langages qui étaient autrefois considérés comme "interprétés", par exemple JavaScript.

starblue
la source
5
De plus, le moteur d'exécution JavaScript V8 de Google ne se contente pas de faire une compilation partielle juste à temps. Il compile toujours en code natif, en fait, V8 n'a même pas d'interprète. Il n'a que le compilateur (similaire à Maxine, mais contrairement à Maxine V8 n'a qu'un seul compilateur). Ces trois exemples (GCJ, Maxine et V8) prouvent encore plus fortement votre point de vue: il n'existe pas de langage interprété ou de langage compilé. Un langage n'est ni interprété ni compilé. Une langue est juste (c'est en fait une citation de Shriram Krishnamurthi).
Jörg W Mittag
3
Pourquoi parlez-vous de javascript dans une question java?
Koray Tugay
1
@KorayTugay Juste à titre d'exemple. Je ne veux certainement pas laisser entendre que Java et Javascript ont autre chose en commun que les quatre premières lettres de leur nom.
starblue
Au moins une différence de langage interprété et compilé ne signifierait-il pas qu'un langage compilé binaire ne peut pas voir son flux d'exécution changé à tout moment, alors qu'un langage interprété est très obéissant à certains des fonctionnements actuels des fonctions? Les bibliothèques en C sont une option tandis que dans d'autres langues, vous ne pouvez pas avoir un objet tableau sans une extension binaire C qui peut être mise à jour ou être un code complètement différent sur une autre plate-forme. Le langage de script pourra fonctionner sur les deux, tandis que le langage compilé aurait besoin d'un autre binaire pour être exécuté
Eaton Emmerich
53

Java est compilé en bytecode, qui entre ensuite dans la machine virtuelle Java, qui l'interprète.

Soie de midi
la source
33
... mais pas strictement précis.
Stephen C
2
JVM peut choisir de ne pas «interpréter» le bytecode. Il peut le compiler par JIT et l'exécuter directement.
Mehrdad Afshari
1
JIT ne l'exécute pas techniquement directement. C'est juste se souvenir de la façon dont cela a été exécuté.
cletus
Mehrdad: D'accord, je n'ai pas décrit les opérations éventuellement JIT ici, car je considère cela jusqu'à la JVM, et je gardais ma réponse simple de toute façon :)
Noon Silk
7
cletus: Après JIT, il sera directement exécuté. JIT lit un morceau de bytecode (par exemple, une méthode complète ) et compile en code machine et y saute.
Mehrdad Afshari
12

Java est un langage de programmation compilé, mais plutôt que de compiler directement en code machine exécutable, il se compile en une forme binaire intermédiaire appelée code d'octet JVM. Le code d'octet est ensuite compilé et / ou interprété pour exécuter le programme.

Sam Harwell
la source
11

Un peu des deux. Tout d'abord java compilé (certains préféreraient dire «traduit») en bytecode, qui ensuite soit compilé, soit interprété selon l'humeur de JIT.

maykeye
la source
32
C'est un logiciel avancé, pour avoir développé des humeurs :)
Thorarin
5
Le JIT est en effet un logiciel très sophistiqué, qui peut effectuer des optimisations basées sur des informations d'exécution (comme un profileur), ce qu'un compilateur en avance ne peut pas faire (car il ne dispose pas d'informations sur le comportement d'exécution de un programme à l'avance). Mais il n'a probablement pas vraiment d'humeur ... :-)
Jesper
5

Java fait à la fois la compilation et l'interprétation,

En Java, les programmes ne sont pas compilés dans des fichiers exécutables ; ils sont compilés en bytecode (comme indiqué précédemment), que la JVM (Java Virtual Machine) interprète / exécute ensuite à l'exécution. Le code source Java est compilé en bytecode lorsque nous utilisons le compilateur javac. Le bytecode est enregistré sur le disque avec l'extension de fichier .class .

Lorsque le programme doit être exécuté, le bytecode est converti, le bytecode peut être converti à l'aide du compilateur juste à temps (JIT). Le résultat est un code machine qui est ensuite introduit dans la mémoire et exécuté.

Javac est le compilateur Java qui compile le code Java en Bytecode. JVM est une machine virtuelle Java qui exécute / interprète / traduit le Bytecode en code machine natif. En Java, bien qu'il soit considéré comme un langage interprété, il peut utiliser la compilation JIT (Just-in-Time) lorsque le bytecode est dans la JVM. Le compilateur JIT lit les bytecodes dans de nombreuses sections (ou dans leur intégralité, rarement) et les compile dynamiquement en code machine afin que le programme puisse s'exécuter plus rapidement, puis mis en cache et réutilisé plus tard sans avoir besoin d'être recompilé. Ainsi, la compilation JIT combine la vitesse du code compilé avec la flexibilité d'interprétation.

Un langage interprété est un type de langage de programmation pour lequel la plupart de ses implémentations exécutent des instructions directement et librement, sans compiler au préalable un programme en instructions en langage machine. L'interpréteur exécute le programme directement, traduisant chaque instruction en une séquence d'un ou plusieurs sous-programmes déjà compilés en code machine.

Un langage compilé est un langage de programmation dont les implémentations sont généralement des compilateurs (traducteurs qui génèrent du code machine à partir du code source), et non des interprètes (exécuteurs pas à pas du code source, où aucune traduction avant l'exécution n'a lieu)

Dans les implémentations de langage de programmation modernes comme en Java, il est de plus en plus populaire pour une plate-forme de fournir les deux options.

premier
la source
Devrait être «le bytecode peut être converti» plutôt que « est converti». Les spécifications Java définissent le bytecode. Que ce bytecode soit exécuté (a) directement dans le matériel , (b) via un interpréteur, (c) compilé au préalable, ou (d) partiellement compilé à la volée au moment de l'exécution sont tous laissés comme détails d'implémentation. Notez que ces quatre options ont en effet été utilisées par diverses implémentations Java réelles.
Basil Bourque
Merci de l'avoir signalé. Alors, que se passe-t-il si le bytecode n'est pas converti en code machine? Je peux penser à un scénario où le bytecode est le jeu d'instructions natif pour certains processeurs et où il n'y a pas besoin de conversion. Ou est-ce que je manque quelque chose.
prime le
Cliquez sur le lien que j'ai donné pour la technologie Jazelle DBX (Direct Bytecode eXecution) , où un sous-ensemble de bytecode JVM est les instructions machine natives du CPU (en quelque sorte). Sans cela, vous obtenez le code machine généré à partir du bytecode (a) de l'interpréteur (à la volée), (b) du compilateur à l'avance, ou (c) à la volée avec un compilateur juste à temps ( interprété dans un premier temps, puis parfois compilé et mis en cache pendant l'exécution).
Basil Bourque
-2

Java est un langage compilé par octets ciblant une plate-forme appelée Java Virtual Machine qui est basée sur la pile et a des implémentations très rapides sur de nombreuses plates-formes.

Hobbs
la source
1
Que signifie «compilé par octets»?
Jesper
2
@Jesper: "Byte-compiled" signifie généralement "compilé en bytecode". «Bytecode» est un terme général qui couvre toute sorte de code intermédiaire non textuel (généralement non exécutable par machine).
Greg Hewgill
-3

Citation de: https://blogs.oracle.com/ask-arun/entry/run_your_java_applications_faster

Les développeurs d'applications peuvent développer le code d'application sur l'un des différents systèmes d'exploitation disponibles sur le marché aujourd'hui. Le langage Java est à ce stade indépendant du système d'exploitation. Le code source brillant écrit par le développeur d'applications Java est maintenant compilé en code Java Byte qui, dans la terminologie Java, est appelé compilation côté client. Cette compilation en code Java Byte est ce qui permet aux développeurs Java d '«écrire une fois». Le code Java Byte peut s'exécuter sur n'importe quel système d'exploitation et serveur compatible, rendant ainsi le code source indépendant du système d'exploitation / serveur. Après la création du code Java Byte, l'interaction entre l'application Java et le système d'exploitation / serveur sous-jacent est plus intime. Le voyage continue - La structure des applications d'entreprise exécute ces codes d'octet Java dans un environnement d'exécution appelé Java Virtual Machine (JVM) ou Java Runtime Environment (JRE). La JVM a des liens étroits avec le système d'exploitation et le matériel sous-jacents, car elle exploite les ressources offertes par le système d'exploitation et le serveur. Le code Java Byte est maintenant compilé en un code exécutable en langage machine qui est spécifique à la plate-forme. Ceci est appelé compilation côté serveur.

Je dirais donc que Java est définitivement un langage compilé.

Teo
la source