Java a la JVM, qu'est-ce que C a?

15

Je sais que C a un compilateur, mais qu'est-ce qui détermine les performances d'exécution?

Par exemple, dans un bloc if else, que se passe-t-il si le code contient uniquement tous les if au lieu de if elses, qu'est-ce qui détermine que tous les if seront exécutés? En Java, ce serait la JVM, mais en C, qu'est-ce que le compilateur d'exécution?

scerrecrow
la source
16
Une nuance utile à apprendre est que les langues ne sont que des langues. Vous pouvez créer un compilateur qui prend le code C et le fait fonctionner dans la JVM par exemple.
Telastyn
10
+1. C'est une très bonne question. Je ne voterais pas pour son ignorance - c'est une merveille que plus d'étudiants Java ne demandent pas cela.
djechlin
Vous pouvez également compiler Java en code machine et éviter la JVM ...
AK_
2
Aussi: Langage de programmation! = Framework! = Bibliothèque d'exécution! = Compilateur! = Compilateur juste à temps! = Interperter
AK_

Réponses:

17

En Java, la machine virtuelle exécute votre code, mais les compilateurs C génèrent du code que la vraie machine exécute. Pour être précis, dans les deux cas, votre programme finit par être converti en code machine réel, mais dans le cas de Java, il y a une étape intermédiaire de compilation en bytecode JVM.

Les programmes Java sont donc convertis en instructions réelles par la JVM lorsque vous les chargez, tandis que les programmes C sont déjà convertis en instructions réelles par le compilateur avant d'être exécutés.

vrostu
la source
20
Il existe des compilateurs qui prennent Java et produisent du code machine. Par exemple Excelsior Jet . Il existe également des interpètres pour C ( picoc ) qui ne génèrent jamais de code qu'une vraie machine exécute. Les langues sont des langues. Les implémentations sont des implémentations. Confondre les deux peut être déroutant pour les gens.
6

Mis à part le code machine, il n'existe aucun langage de programmation qui s'exécute directement sur le matériel, dans le sens où vous ne pouvez pas lui fournir le texte source littéral. Toutes les implémentations réelles doivent traduire le programme source dans le langage de la "machine".

Pour certaines implémentations, il est traduit statiquement. Nous appelons généralement ces implémentations "compilées". Pour d'autres, il est traduit sous une forme intermédiaire, qui est ensuite traduite dynamiquement lors de l'exécution du programme. Nous appelons généralement ces implémentations "interprétées". Il existe un continuum de possibilités entre celles-ci, et même de nombreux processeurs modernes font la traduction dynamique dans le cadre de son cœur d'exécution.

Même lorsque votre programme est compilé statiquement bien avant son exécution, à moins que vous n'écriviez un micrologiciel, il est rare que le code compilé s'exécute directement sur le métal nu sans rien le prendre en charge. Le système d'exploitation fournit une machine virtuelle pour les programmes de l'espace utilisateur, offrant souvent des fonctionnalités telles que l'illusion que vous avez un processeur pour vous tout seul. L'illusion d'un espace mémoire plat qui pourrait être plus grand que la RAM physique attachée à la machine est même appelée «mémoire virtuelle».

En plus de cela, même lorsque vous programmez en C, il y a une machine virtuelle C! Il est traditionnellement appelé "le runtime C", ou CRT pour faire court.

Étant donné que C est principalement traduit directement en code assembleur / machine bien à l'avance (sur certaines plates-formes, il peut également y avoir du code threadé et qui peut être considéré comme faisant partie de la machine virtuelle), la machine virtuelle ne doit généralement gérer que le démarrage et fermer.

Le démarrage implique généralement la configuration de la pile et du tas; le système d'exploitation vous les fournit rarement, et c'est le travail du langage de programmation de les fournir au programmeur. Sur certaines plates-formes, il peut y avoir une initialisation de la gestion du signal, la configuration du thread "principal" dans un environnement multi-thread, l'exécution de constructeurs globaux au cas où le programme a été lié au code C ++, la gestion de bibliothèques liées dynamiquement, ou là un traitement peut être nécessaire pour configurer argc / argv et envp. Enfin, CRT transfère le contrôle au principal.

En ce qui concerne l'arrêt, de nombreux systèmes d'exploitation peuvent tuer un processus de manière impure, donc l'arrêt n'a pas besoin de faire grand-chose. L'essentiel est de traiter les appels atexit () dans le cas où le programme se ferme correctement.

Pseudonyme
la source
2
Le runtime C et la JVM sont des bêtes complètement différentes. Le CRT n'est qu'une bibliothèque.
DeadMG
J'ai édité la réponse pour rendre les choses un peu plus claires. Soit dit en passant, la JVM et VirtualBox sont également des bêtes complètement différentes.
Pseudonyme du
@Pseudonym: pas vraiment. Bon, d'accord, VirtualBox est un virtualiseur, alors que la JVM typique est un émulateur, mais si vous remplacez par exemple VirtualBox par QEmu dans votre phrase, alors les deux sont en fait les mêmes.
Jörg W Mittag