Je pense qu'il y a une distinction à faire, mais ce n'est pas nécessairement entre «compilé» et «géré». Ce ne sont pas des opposés; un langage peut être compilé et non géré, ou interprété (non compilé) et géré, ou les deux, ou même ni l'un ni l'autre.
Un langage "compilé" est simplement un langage dans lequel il y a une étape qui transforme le code source écrit par le développeur en un "bytecode" plus régulier qui est exécuté par la machine. La «machine» peut être le processeur réel, ou une «machine virtuelle» qui effectue des opérations supplémentaires sur les bytecodes pour les traduire en instructions machine «natives». L'antonyme d'un langage "compilé" est un langage "interprété", dans lequel le code source est transformé en instructions de bytecode au moment de l'exécution, ligne par ligne au fur et à mesure de leur exécution, sans étape de compilation. Un hybride entre eux est "jitting", de "JIT" (Just In Time), qui est généralement interprété comme une étape unique par la machine exécutante;
Un langage "géré" est un langage conçu pour produire des programmes qui sont consommés dans un environnement d'exécution spécifique, qui comprend presque toujours un interpréteur de bytecode; une "machine virtuelle" qui prend le code du programme et effectue une transformation supplémentaire spécifique à la machine ou à l'environnement. L'environnement peut également inclure la gestion de la mémoire, comme un «garbage collector» et d'autres fonctionnalités de «sécurité» destinées à maintenir le programme dans son «bac à sable» d'espace et d'outils, mais ces fonctionnalités ne sont pas le seul domaine des runtimes «gérés» . Pratiquement tous les langages interprétés peuvent être considérés comme gérés, car ils nécessitent que l'interpréteur s'exécute sous les lignes de code "utilisateur" en cours d'exécution. De plus, les langages JVM et .NET (Java, Scala, C #, VB, F #, IronWwhat) sont compilés dans un langage intermédiaire ou IL, qui est superficiellement similaire dans sa forme et sa fonction à un langage d'assemblage binaire, mais n'adhère pas à 100% à un ensemble d'instructions "natif". Ces instructions sont exécutées par la JVM ou par le CLR de .NET, qui les traduit efficacement en instructions binaires natives spécifiques à l'architecture CPU et / ou au système d'exploitation de la machine.
Ainsi, les langues peuvent généralement être décrites comme "compilées" ou "interprétées", et comme "non gérées" (ou "natives") et "gérées". Il existe des langages qui peuvent être décrits comme n'importe quelle combinaison de ceux-ci, à l'exception d'un éventuel "natif interprété" (qui ne serait vrai que pour les opcodes hexadécimaux écrits à la main, où ce qui est écrit par le développeur est ce qui est exécuté); si vous considérez la couche d'interprétation comme un "runtime" (ce qui est facile à argumenter et difficile à argumenter), alors tous les langages interprétés sont "gérés".
Si vous voulez devenir technique, presque tous les programmes ciblant un OS multitâche de nos jours sont "gérés"; le système d'exploitation créera une "machine virtuelle" pour chaque programme en cours d'exécution, dans laquelle le programme pense (ou du moins n'a pas besoin de savoir le contraire) que c'est la seule chose en cours d'exécution. Le code peut effectuer des appels en lui-même et vers d'autres bibliothèques référencées comme si ce programme était la seule chose chargée en mémoire; de même, les appels d'allocation de RAM et d'autres mémoires plus élevées pour stocker et manipuler des données et des dispositifs de contrôle sont codés comme si toute l'architecture de la mémoire était disponible. La machine virtuelle (et le système d'exploitation derrière elle) traduit ensuite divers pointeurs de mémoire vers l'emplacement réel du programme, ses données et les crochets vers les pilotes de périphérique, etc. Cela se fait le plus souvent en appliquant un décalage de mémoire (chaque machine virtuelle obtient un bloc de 2 Go. ou quoi que ce soit de la mémoire, à partir de l'adresse X que le programme peut traiter comme si ce X était l'adresse 0) et en tant que telle est très bon marché, mais il y a d'autres choses dont le noyau du système d'exploitation est responsable, telles que la planification des processus et la communication interprocessus, qui sont plus difficile à gérer. Cependant, ce modèle de base n'est généralement pas considéré comme "géré", car le programme n'a pas besoin de savoir qu'il est exécuté par une machine virtuelle et est souvent toujours responsable de garder sa mémoire allouée "propre". Un programme qui a été conçu pour être exécuté sur la ligne de commande MS-DOS peut être exécuté sur des systèmes d'exploitation Windows plus récents qui n'ont même plus l'environnement MS-DOS sous eux; le programme reçoit à la place un environnement de "console virtuelle", et à condition qu'il n'essaye pas de quitter ce "bac à sable"