82 votes

Différences entre le bytecode MSIL et Java?

Je suis nouveau sur .Net et j'essaie d'abord de comprendre les bases. Quelle est la différence entre le bytecode MSIL et Java?

76voto

Motti Points 32921

D'abord, laissez-moi vous dire que je ne pense pas que les différences subtiles entre le bytecode Java et MSIL est quelque chose qui devrait déranger un novice .NET développeur. Ils servent tous les deux le même but, à savoir la définition d'un abrégé de la machine cible qui est une couche au-dessus de la machine physique utilisé dans la fin.

MSIL et le bytecode Java sont très semblables, en fait, il existe un outil appelé Sauterelle qui se traduit par MSIL pour le bytecode Java, je faisais partie de l'équipe de développement pour la Sauterelle, donc je peux partager un peu de mes (fanée) de la connaissance. Veuillez noter que j'ai arrêté de travailler sur ce autour de lors de .NET framework 2.0 est sorti tellement de certaines de ces choses ne peut pas être plus vrai (si s'il vous plaît laissez un commentaire et je vais le corriger).

  • .NET permet de types définis par l'utilisateur qui se trouvent sur la pile (struct).
  • .NET prend en charge non signé types, ce qui rend le jeu d'instructions un peu plus riche.
  • Java comprend la spécification d'exception de méthodes dans le bytecode. Bien que la spécification d'exception est généralement appliquée par le compilateur, il peut être exécuté par la JVM si un chargeur de classe autre que celui par défaut est utilisé.
  • .NET génériques sont exprimés en IL alors que Java génériques utilisez uniquement le type d'effacement.
  • .NET attributs n'ont pas d'équivalent en Java (est-ce toujours le cas?).
  • .NET enums ne sont pas beaucoup plus que les wrappers autour de types d'entiers alors que Java enums sont à peu près à part entière classes (grâce à Internet Ami pour les commentaires).
  • .NET a out et ref paramètres.

Il y a d'autres différences de langue, mais la plupart d'entre eux ne sont pas exprimées à l'octet de code de niveau, par exemple si la mémoire est de Java non-static les classes internes (qui n'existent pas dans .NET) ne sont pas un code binaire en fonction, le compilateur génère un argument supplémentaire à l'intérieur du constructeur de la classe et passe à l'objet extérieur. La même chose est vraie pour les .NET des expressions lambda.

24voto

Justin Points 5321

CIL (le vrai nom de MSIL) et le bytecode Java sont plus les mêmes qu'ils sont différents. Il y a quelques différences importantes:

1) CIL a été conçu dès l'origine pour servir de cible pour plusieurs langues. En tant que tel, il prend en charge beaucoup plus riches type de système, y compris les entiers signés et non signés, les types de valeur, les pointeurs, les propriétés, les délégués, les événements, les génériques, un objet avec une seule racine, et plus encore. CIL qui prend en charge les fonctionnalités pas requis lors de la première CLR langages (C# et VB.NET) tels que les fonctions globales et de la queue-appel d'optimisations. En comparaison, le bytecode Java a été conçu comme une cible pour le langage Java et reflète beaucoup de contraintes trouvé en Java lui-même. Il serait beaucoup plus difficile d'écrire C ou de l'utilisation de bytecode Java.

2) CIL a été conçu pour s'intégrer facilement dans les bibliothèques natives et code non managé

3) le bytecode Java a été conçu pour être interprété ou compilé tout CIL a été conçu en supposant compilation JIT. Cela dit, la mise en œuvre initiale de Mono utilisé les services d'un interprète à la place d'une équipe commune d'enquête.

4) CIL a été conçu (et spécifié) d'avoir un homme de lecture et d'écriture de l'assemblée forme de langage que les cartes directement sur le bytecode forme. Je crois que le bytecode Java est (comme son nom l'indique, destiné à être uniquement lisible par la machine. Bien sûr, le bytecode Java est relativement facile à décompilé en arrière à l'original Java et, comme indiqué ci-dessous, il peut aussi être "démonté".

Il est à noter que la JVM (la plupart d'entre eux) est plus optimisé que le CLR (l'un d'eux). Donc, la performance brute pourrait être une raison de préférer le ciblage de bytecode Java. C'est un détail d'implémentation.

Certaines personnes disent que le bytecode Java a été conçu pour être multi-plateforme, tandis que CIL a été conçu pour Windows uniquement. Ce n'est pas le cas. Il y a quelques "Windows"ismes dans le .NET framework, mais il n'en existe pas dans le CIL.

Comme un exemple de nombre de point 4) ci-dessus, j'ai écrit un jouet Java à CIL compilateur a tout à l'arrière. Si vous nourrissez ce compilateur Java suivantes du programme:

class Factorial{
    public static void main(String[] a){
    System.out.println(new Fac().ComputeFac(10));
    }
}

class Fac {
    public int ComputeFac(int num){
    int num_aux ;
    if (num < 1)
        num_aux = 1 ;
    else 
        num_aux = num * (this.ComputeFac(num-1)) ;
    return num_aux ;
    }
}

mon compilateur va cracher le suivant CIL:

.assembly extern mscorlib { }
.assembly 'Factorial' { .ver  0:0:0:0 }
.class private auto ansi beforefieldinit Factorial extends [mscorlib]System.Object
{
   .method public static default void main (string[] a) cil managed
   {
      .entrypoint
      .maxstack 16
      newobj instance void class Fac::'.ctor'()
      ldc.i4 3
      callvirt instance int32 class Fac::ComputeFac (int32)
      call void class [mscorlib]System.Console::WriteLine(int32)
      ret
   }
}

.class private Fac extends [mscorlib]System.Object
{
   .method public instance default void '.ctor' () cil managed
   {
      ldarg.0
      call instance void object::'.ctor'()
      ret
   }

   .method public int32 ComputeFac(int32 num) cil managed
   {
      .locals init ( int32 num_aux )
      ldarg num
      ldc.i4 1
      clt
      brfalse L1
      ldc.i4 1
      stloc num_aux
      br L2
   L1:
      ldarg num
      ldarg.0
      ldarg num
      ldc.i4 1
      sub
      callvirt instance int32 class Fac::ComputeFac (int32)
      mul
      stloc num_aux
   L2:
      ldloc num_aux
      ret
   }
}

Ceci est valable CIL programme qui peut être introduit dans un CIL assembleur comme ilasm.exe pour créer un fichier exécutable. Comme vous pouvez le voir, CIL est entièrement humain, de lecture et d'écriture de la langue. Vous pouvez facilement créer valide CIL programmes dans tout éditeur de texte.

Vous pouvez aussi compiler le programme Java ci-dessus avec l' javac compilateur, puis exécutez la classe résultante des fichiers par le biais de l' javap "désassembleur" pour obtenir le suivant:

class Factorial extends java.lang.Object{
Factorial();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
   4:   return

public static void main(java.lang.String[]);
  Code:
   0:   getstatic   #2; //Field java/lang/System.out:Ljava/io/PrintStream;
   3:   new #3; //class Fac
   6:   dup
   7:   invokespecial   #4; //Method Fac."<init>":()V
   10:  bipush  10
   12:  invokevirtual   #5; //Method Fac.ComputeFac:(I)I
   15:  invokevirtual   #6; //Method java/io/PrintStream.println:(I)V
   18:  return

}

class Fac extends java.lang.Object{
Fac();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
   4:   return

public int ComputeFac(int);
  Code:
   0:   iload_1
   1:   iconst_1
   2:   if_icmpge   10
   5:   iconst_1
   6:   istore_2
   7:   goto    20
   10:  iload_1
   11:  aload_0
   12:  iload_1
   13:  iconst_1
   14:  isub
   15:  invokevirtual   #2; //Method ComputeFac:(I)I
   18:  imul
   19:  istore_2
   20:  iload_2
   21:  ireturn
}

L' javap de sortie n'est pas compilable (à ma connaissance), mais si on le compare à la CIL de sortie ci-dessus, vous pouvez voir que les deux sont très similaires.

22voto

Guy Starbuck Points 14241

Ils sont essentiellement de faire la même chose, MSIL est la version de Microsoft du bytecode Java.

Les principales différences à l'interne sont:

  1. Bytecode a été développé à la fois pour la compilation et l'interprétation, tout en MSIL a été développé expressément pour la compilation JIT
  2. MSIL a été développé pour prendre en charge plusieurs langages (C# et VB.NET, etc.) rapport du Bytecode en cours de rédaction pour juste Java, résultant en Bytecode être plus similaire à Java syntaxiquement qu'IL est spécifique .NET de la langue
  3. MSIL a plus explicites de la délimitation entre la valeur et les types référence

Beaucoup plus d'informations et une comparaison détaillée peut être trouvée dans cet article par K John Gough (document postscript)

2voto

GHad Points 4131

Il n'y a pas beaucoup de différences. Les deux sont des formats intermédiaires du code que vous avez écrit. Lorsqu'il est exécuté, les machines Virtuelles qui exécutent le langage intermédiaire géré cela signifie que la Machine Virtuelle contrôle les variables et les appels. Il y a même une langue dont je ne me rappelle maintenant que peut courir .Net et Java de la même façon.

Bref, c'est juste un autre format pour la même chose

Edit: Trouvé le langage (en plus de la Scala): Il est FAN (http://www.fandev.org/), a l'air très intéressant, mais pas de temps encore à évaluer

2voto

slim Points 12620

CIL aka MSIL est conçu pour être lisible par l'homme. Le bytecode Java n'est pas.

Pense du bytecode Java comme étant en code machine pour le matériel qui n'existe pas (mais qui Jvm imiter).

CIL est plus comme langage d'assemblage - une étape de code machine, tout en restant lisible par l'homme.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X