Est le CLR une machine virtuelle?
J'ai lu un livre qui se réfère à l' .net CLR comme une machine virtuelle? Quelqu'un peut-il justifier cela? Qu'est-ce que la raison nous avons besoin de la notion de machines virtuelles sur certaines plates-formes de développement?
N'est-il pas possible de développer un cadre autochtone [sans machine virtuelle] qui est entièrement orienté objet et aussi puissant .net?
Le livre qui fait référence à CLR que la machine virtuelle est "Professionnel .Net Framework 2.0".
- C'est vraiment juste un argument de plus à ce qu'est une "machine virtuelle" est. Notez que les "indigènes" jeu d'instructions x86 peut être considéré comme une machine virtuelle du jeu d'instructions, interprété par le PROCESSEUR. Donc, si le CLR s'exécute sur une machine virtuelle, est-il possible pour elle de ne pas être considéré comme une machine virtuelle?
- Le CLR ne fonctionne pas sur une "machine virtuelle". Le CLR est un juste-à-temps compilateur et un garbage collector. Lorsque le CLR doit invoquer dans une bibliothèque en C il n'ont pas les frais généraux qui JNI n'parce qu'il est déjà en code natif, ce qui il a à faire est d'appuyer les arguments sur la pile et de sauter à la méthode. Alors que Java a à faire toutes sortes de cher de gymnastique pour faire que le scénario de travail, résultant en une très lente pont en code natif.
- fonctionne très bien à l'intérieur de VMware, VirtualBox, Virtual PC, etc, donc je ne sais pas pourquoi vous faites un universel prétendre qu'il ne s'exécute pas sur les ordinateurs virtuels. Mais je suppose que vous vouliez dire, si CLR est elle-même une VM, pas de savoir s'il s'exécute sur le dessus de l'un. Comme vous le dites, le CLR a un compilateur JIT et un garbage collector. Mais vous avez raté le vérificateur. Et le modèle de sécurité. Et sa propre implémentation des threads distincts de l'OS. Et son propre chargeur. De l'exécution et de l'introspection, y compris un système sophistiqué de débogage de l'API. C'est certainement une machine virtuelle.
- Il choisit de partager beaucoup de choses avec la machine physique, telles que l'adresse de l'espace (qui est virtualisé sur la machine physique de toute façon), afin de réduire la quantité de travail que p/invoke a faire.... mais selon les types impliqués p/invoke fait beaucoup de travail, et même pour les types simples, il est nulle part près d'aussi simple que de "pousser les arguments sur la pile et de sauter". Chaque géré/native de transition implique de changer le collecteur d'ordures de l'état, à la broche de paramètres passés par référence, et aussi pour permettre au gouvernement pour mettre en pause le thread sur le retour en code managé.
- Voigt - oui, si vous ajoutez un groupe de travail, je n'ai jamais spécifié, alors il n'y a plus de travail à faire pour l'appel des indigènes, mais si vous utilisez uniquement blittable types de la différence entre le CLR et Java devient tout à fait évident. Sans compter poussant les arguments sur la pile, un calli instruction compile à 6 ASM instructions. Je doute sérieusement une interprétation d'une méthode Java pouvez le faire n'importe où près aussi efficace. L'interprétation est ce qui fait une course de méthode Java "virtuel", tandis qu'un exécutant CLR méthode est aussi réel que tout compilé en C++ méthode.
- Mais je n'ai pas "ajouter", le CLR toujours fait ces choses et vous avez choisi de les laisser hors de votre mise en œuvre à l'appui de votre description d'une très fine couche. Mais le code en cours d'exécution avec le CLR est "géré" pas "natif", et géré/native transitions sont compliquées bêtes. Même si une grande partie du travail est effectuée à l'aide de la table de recherches (le même type de démarche que zéro charge la gestion des exceptions), de sorte qu'il n'apparaisse pas sur le site d'appel, le fait demeure que, pour chacune de ces transitions a le potentiel pour être un point de synchronisation avec le garbage collector.
Vous devez vous connecter pour publier un commentaire.
Il y a beaucoup de fausses idées ici. Je suppose que vous pourriez penser .Net comme une machine virtuelle si tu le voulais vraiment, mais regardons comment le .Net Framework gère votre code. Le scénario typique ressemble à ceci
Il y a quelques points importants ici, mais le grand est que à aucun moment aucun code jamais interprété. Au lieu de cela, vous pouvez le voir dans l'étape 5 qu'il est compilé en code natif. Cette énorme de différence que de les charger dans une machine virtuelle, pour plusieurs raisons:
Je suppose que vous pourriez appeler cela une machine virtuelle, dans le sens de la Gigue résumés loin les détails de la machine réelle de la part du développeur. Personnellement, je ne pense pas que c'est vraiment bon, parce que pour beaucoup de gens, une machine virtuelle implique un temps d'exécution de l'abstraction à l'écart de code natif pour .Net les programmes d' n'existe pas.
Un autre point important concernant l'ensemble de ce processus qui distingue vraiment à part une "machine virtuelle" de l'environnement, c'est que c'est seulement le typique processus. Si vous le voulez vraiment, vous pouvez pré-compiler un .Net de l'assemblée avant de la distribution et de déployer du code natif directement à l'utilisateur final (indice: il est plus lent dans l'ensemble au cours de la vie du programme, parce que vous perdez de la machine-optimisations spécifiques). Bien sûr, vous avez encore besoin de la .Net runtime installé, mais à ce point c'est vraiment pas très différente de toute autre exécution de l'API, c'est plus une collection dll avec une belle API, vous pouvez lier contre, comme vous avez pu le VB ou C temps de fonctionnement de Microsoft est également livré avec Visual Studio. Ce genre de faut de l'IL de l'image, rendant la VM moniker beaucoup plus difficile à justifier. (Je dis "genre de", car IL est toujours déployé et utilisé pour vérifier le même code, mais il n'est jamais lui-même touché pour l'exécution).
Un autre révélateur est le manque d'une VM processus. Lorsque vous exécutez votre application, il n'y a pas de commune "bac à sable" processus qui s'exécute. A comparer avec Java, où si vous ouvrez le gestionnaire des tâches lorsqu'un programme est en cours d'exécution, vous verrez un processus spécifiquement pour la machine virtuelle Java, et l'application du processus réel est un fil à l'intérieur de l'espace créé par la machine virtuelle. Dans .Net, vous voyez l'application du processus dans le gestionnaire des tâches de Windows directement.
En résumé: on pourrait dire qu'IL + CLR + JIT, ensemble, faire en quelque sorte une machine virtuelle. Personnellement, je ne le pense pas, mais je ne vais pas discuter avec vous si vous croyez que. Le point que je veux faire, c'est que lorsque vous dites à quelqu'un qu' .Net s'exécute dans une machine virtuelle avec aucune autre explication, l'idée que vous communiquez à personne, elle est "interprété bytecode dans un processus hôte." Et c'est tout simplement faux.
gmcs hello.cs
et voici le kicker, pour exécutermono hello.exe
qui ressemble à un processus en cours d'exécution, il m'Similaire à la Machine Virtuelle Java (JVM), l' .net CLR est un byte-code de l'interprétation de la machine virtuelle.
La JVM interprète des programmes qui contiennent java byte codes et les .net CLR interprète des programmes qui contiennent ce que Microsoft appelle "le Langage Intermédiaire" des instructions. Il y a des différences entre ces octets de codes, mais les machines virtuelles sont similaires et aspire à fournir des fonctionnalités similaires.
Ces deux machine virtuelle implémentations ont la possibilité de compiler leur entrée bytecode pour le langage machine de l'ordinateur qu'ils sont en cours d'exécution sur. Ceci est appelé "Juste À Temps de Compilation (JIT)" et le code de sortie produite est appelée "JIT code." Parce que le JIT code contiennent des séquences d'instructions en langage machine du PROCESSEUR de l'ordinateur, ce code est parfois désigné comme "natifs" du code.
Cependant, JIT code est qualitativement et quantitativement différente de code natif, comme expliqué ci-dessous. Pour cette raison, cet article considère JIT code pour être rien de plus qu'un natif de mise en œuvre de la Machine Virtuelle lors de l'exécution d'un particulier bytecode programme.
Une caractéristique que ces deux Machines Virtuelles (VMs) aspire à fournir est de la sécurité dans le formulaire de prévenir un certain nombre de dangereuses erreurs de programmation. Par exemple, le titre de ce forum d'un site web, stackoverflow, est inspiré par un tel type de dangereux erreur qui est possible en code natif.
Afin d'assurer la sécurité et la sécurité de l'exécution, le VMs de mettre en œuvre la sécurité de type à la "Machine Virtuelle" de niveau. Les affectations de mémoire virtuelle sont nécessaires pour stocker le type de données qui est tenue à cet emplacement de la mémoire. Par exemple, si un nombre entier est poussé sur la pile, il n'est pas possible de la pop un double de la pile. C-style "unions", sont interdites. Les pointeurs et l'accès direct à la mémoire sont interdites.
Nous ne pouvions pas obtenir les mêmes avantages en imposant un langage orienté objet-cadre sur les développeurs si le résultat est un fichier binaire natif comme un fichier EXE. Dans ce cas, nous ne serions pas en mesure de distinguer entre les binaires générés à l'aide du cadre et des Exe généré par un utilisateur malveillant employant d'autres sources que le cadre.
Dans le cas de la VMs, le type de sécurité est appliquée au "niveau le plus bas" que le programmeur est autorisé à accéder. (En négligeant pour l'instant qu'il est possible d'écrire géré en code natif, ce qui est.) Par conséquent, aucun utilisateur ne rencontrerez une application qui effectue l'une des opérations dangereuses qui nécessitent un accès direct à la mémoire des emplacements et des pointeurs.
Dans la pratique, l' .net CLR une manière d'écrire du code natif qui peut être appelé par .net "géré" du code. Dans ce cas, la charge est sur le code natif à l'auteur de ne pas faire du pointeur et de la mémoire des erreurs.
À la fois comme la JVM et .net CLR effectuer la compilation JIT, soit VM crée en fait un natif binaire compilé à partir du bytecode fourni. Cette "JIT code" effectue plus rapidement que la VM est l'interprète de l'exécution, parce que même le langage machine code produit par JIT contient toutes les VM de sécurité vérifie que l'ordinateur virtuel effectuer. En conséquence, l'équipe de code de sortie n'est pas aussi rapide que le code natif qui seraient normalement pas contenir de nombreux au moment de l'exécution des contrôles. Toutefois, cette vitesse de la performance inconvénient est échangé pour une amélioration de la fiabilité, y compris la sécurité; en particulier, l'utilisation de non initialisé de stockage est empêché, de sécurité du type de missions est appliquée, de la portée de la vérification est effectuée (donc pile et tas dépassements de la mémoire tampon empêché), objet des durées de vie sont gérées par la collecte des ordures, l'allocation dynamique est de type sécurisé. Un environnement d'exécution de ce moment de l'exécution comportement de contrôle, la mise en œuvre de la spécification d'une machine virtuelle et n'est guère plus qu'un langage machine de la réalisation d'une machine virtuelle.
La "Machine Virtuelle" partie se réfère au fait que .NET code est compilé en EXE et DLL comme "Intermédiaire" de l'Assemblée de la langue (IL) pour s'exécuter sur une machine virtuelle, par opposition à réel CPU langage d'assemblage. Puis, au moment de l'exécution de l'ILM est converti en CPU réel de l'assemblée pour l'exécution (appelé Just-in-time ou JIT compiler).
Bien sûr, vous pourriez écrire un .NET compilateur de sorte qu'il serait compilé dans l'UC de l'assemblée de la langue au lieu de l'IL. Cependant, ce ne serait pas portable pour tous les Cpu - vous auriez à compiler une version différente pour chaque système d'exploitation/PROCESSEUR paire. Mais en compilant dans ILM, vous laissez la "Machine Virtuelle" gérer le PROCESSEUR et l'OS de choses spécifiques.
Je suis un peu vieille école, j'ai donc appeler le CLR une machine virtuelle. Mon raisonnement est que le CLR assemble le code de l'ordinateur à partir d'un intermédiaire de bytecode, qui est ce qu'une machine virtuelle aussi.
Les avantages de la CLR est principalement en raison de la façon dont il assemble le code machine qui utilise le runtime type d'informations.
Vous pouvez développer un cadre autochtone aussi puissant que l' .NET framework à l'aide seulement de types natifs. La seule flexibilité que vous perdez, c'est la capacité à remonter le code natif si jamais vous avez le transport de votre programme à une autre plate-forme sans avoir à recompiler.
L'avantage de la CLR est la liberté d'écrire du code quel que soit le langage de programmation le développeur choisit, depuis que le code sera compilé vers le bas pour CLR avant d'être interprétées dans les appels natifs. L' .NET framework utilise cette compilation JIT pour traiter tout uniformément et de sortie des programmes de travail de la plate-forme en cours de déploiement sur, ce qui est absent de langages compilés.
Ni la machine, ni le CLR faire tout ce qui est sensiblement différente de ce que la plupart des "machines virtuelles" pour d'autres langues également. Moderne, ils utilisent tous JIT pour convertir les instructions (p-code, bytecode, langage intermédiaire d'instructions, appelez ça comme vous voulez) pour "natif de matériel de PROCESSEUR" instructions ("code machine.")
En fait, la première "machine virtuelle" pour ce faire, il a la Causerie de la machine virtuelle. L'auteur de cette innovation, Peter Deutsch, surnommé "la traduction dynamique" au lieu du terme "JIT", qui a été popularisé par Java. Si la Causerie "d'exécution de l'environnement" va être appelé une "machine virtuelle" (et c'est ce qu'il est toujours appelé, alors, de tout et de tous les autres "temps d'exécution des systèmes" que font essentiellement la même chose aussi être considérées comme des "machines virtuelles."
Vous avez beaucoup de précieuses réponses, mais je pense qu'une chose n'a pas encore été mentionnés: la Modularité.
Il est assez difficile d'exporter un OO classe de DLL native. Bien sûr, vous pouvez dire à l'éditeur de liens à l'exportation de la classe et de les importer ailleurs, mais c'est fragile; la Modification d'un seul membre privé dans une classe de rompre la compatibilité binaire, c'est à dire si vous modifiez un fichier DLL sans recompiler tous les autres modules, votre programme va planter horriblement lors de l'exécution.
Il y a des moyens de contourner cela: Par exemple, vous pouvez définir le public des interfaces abstraites, dérivent de ceux et de l'exportation mondiale de l'usine des fonctions à partir de votre fichier DLL. De cette façon, vous pouvez modifier les détails de l'implémentation d'une classe. Mais vous ne pouvez pas déduire de cette classe dans une autre DLL. Et changer l'interface se différencie également de la compatibilité binaire, bien sûr.
Je ne suis pas sûr qu'il y en est une bonne solution pour ce en code natif: Si le compilateur/linker crée code natif au moment de la compilation, il doit connaître l'exacte disposition de la mémoire des classes et/ou des structures qui sont utilisées dans le code. Si la dernière étape de compilation (génération de code natif) est retardée jusqu'à ce qu'une méthode est appelée pour la première fois, ce problème va tout simplement à l'écart: vous pouvez modifier une classe dans une assemblée, et aussi longtemps que l'équipe peut résoudre tous les membres au moment de l'exécution, tout fonctionne bien.
En un mot: Si vous créez un monolithique unique-programme exécutable, vous pourriez probablement avoir plus de fonctions puissantes d' .NET avec un compilateur qui crée code natif. Mais les inconvénients d'avoir un compilateur JIT (installation du framework, un peu plus long temps de démarrage) vraiment ne l'emportent pas sur les avantages dans la plupart des cas.