Unterschiede zwischen MSIL und Java-Bytecode?

Lesezeit: 9 Minuten

Benutzer-Avatar
Benutzer18055

Ich bin neu bei .Net und versuche zuerst, die Grundlagen zu verstehen. Was ist der Unterschied zwischen MSIL und Java-Bytecode?

  • Verwandte Frage: stackoverflow.com/questions/453610/…

    – Frank v

    17. Januar 2009 um 17:09 Uhr

  • Ein etwas allgemeinerer Vergleich findet sich unter: stackoverflow.com/questions/682608/…

    – AR

    16. Juni 2012 um 1:10 Uhr

Benutzer-Avatar
Motti

Lassen Sie mich zunächst sagen, dass ich nicht denke, dass die feinen Unterschiede zwischen Java-Bytecode und MSIL etwas sind, das einen unerfahrenen .NET-Entwickler stören sollte. Beide dienen demselben Zweck, nämlich eine abstrakte Zielmaschine zu definieren, die eine Schicht über der physischen Maschine liegt, die letztendlich verwendet wird.

MSIL und Java-Bytecode sind sehr ähnlich, tatsächlich gibt es ein Tool namens Heuschrecke das MSIL in Java-Bytecode übersetzt, war ich Teil des Entwicklungsteams für Grasshopper, damit ich ein wenig von meinem (verblassten) Wissen teilen kann. Bitte beachten Sie, dass ich aufgehört habe, daran zu arbeiten, als .NET Framework 2.0 herauskam, sodass einige dieser Dinge möglicherweise nicht mehr zutreffen (wenn ja, hinterlassen Sie bitte einen Kommentar und ich werde es korrigieren).

  • .NET erlaubt benutzerdefinierte Typen, die eine Wertesemantik im Gegensatz zu haben regulär Referenzsemantik (struct).
  • .NET unterstützt vorzeichenlose Typen, dies macht den Befehlssatz etwas umfangreicher.
  • Java enthält die Ausnahmespezifikation von Methoden im Bytecode. Obwohl die Ausnahmespezifikation normalerweise nur vom Compiler erzwungen wird, kann sie von der JVM erzwungen werden, wenn ein anderer Klassenlader als der Standardlader verwendet wird.
  • .NET-Generika werden in IL ausgedrückt, während Java-Generika nur verwendet werden Typ löschen.
  • .NET-Attribute haben keine Entsprechung in Java (ist das immer noch wahr?).
  • .NETZ enums sind dabei nicht viel mehr als Wrapper um Integer-Typen Java enums sind ziemlich vollwertige Klassen (danke an Internet Friend für den Kommentar).
  • .NET hat out und ref Parameter.

Es gibt andere Sprachunterschiede, aber die meisten davon werden nicht auf Bytecode-Ebene ausgedrückt, zum Beispiel wenn der Speicher Javas nicht-static Innere Klassen (die in .NET nicht vorhanden sind) sind kein Bytecode-Feature, der Compiler generiert ein zusätzliches Argument für den Konstruktor der inneren Klasse und übergibt das äußere Objekt. Dasselbe gilt für .NET-Lambda-Ausdrücke.

  • In Bezug auf Attribute – Java-Annotationen können so eingestellt werden, dass sie auch im Bytecode erscheinen, daher gibt es ein Äquivalent.

    – Eiche

    31. Mai 2010 um 13:56 Uhr

  • @Oak: Java-Annotationen erlauben nur die Weitergabe von Daten, während .NET-Attribute vollwertige Klassen sind, die über Logik verfügen und vor allem Schnittstellen implementieren können.

    – Fjodor Soikin

    28. August 2011 um 1:57 Uhr


  • Bytecode hat auch separate Rückgabeanweisungen für jede Art von Rückgabetyp, keine Ahnung, ob es tatsächlich zur Typsicherheit beiträgt.

    – Cecil Geschirrspüler

    10. Mai 2013 um 18:55 Uhr

  • Die Tatsache, dass Werttypen in .NET manchmal auf dem Stapel zugewiesen werden können, ist im Vergleich zu der Tatsache, dass dies der Fall ist, von trivialer Bedeutung Wertesemantik; jeder wertartige Speicherort ist eine Instanz. Im Gegensatz dazu ist jeder Speicherort in Java entweder eine primitive oder eine promiskuitive Objektreferenz; es gibt keine anderen Arten.

    – Superkatze

    23. Juli 2013 um 23:40 Uhr

  • Haben Sie sich gefragt, wie sie sich leistungsmäßig vergleichen? Ist MSIL schneller zu interpretieren als Bytecode für zB?

    – Luke T O’Brien

    13. Oktober 2017 um 14:26 Uhr

CIL (der richtige Name für MSIL) und Java-Bytecode sind mehr gleich als unterschiedlich. Es gibt jedoch einige wichtige Unterschiede:

1) CIL wurde von Anfang an darauf ausgelegt, als Ziel für mehrere Sprachen zu dienen. Als solches unterstützt es ein viel reichhaltigeres Typsystem, einschließlich Typen mit und ohne Vorzeichen, Werttypen, Zeigern, Eigenschaften, Delegaten, Ereignissen, Generika, einem Objektsystem mit einem einzigen Stamm und mehr. CIL unterstützt Funktionen, die für die ursprünglichen CLR-Sprachen (C# und VB.NET) nicht erforderlich sind, wie globale Funktionen und Tail-Call-Optimierungen. Im Vergleich dazu wurde Java-Bytecode als Ziel für die Java-Sprache entwickelt und spiegelt viele der Einschränkungen wider, die in Java selbst zu finden sind. Es wäre viel schwieriger, C oder Scheme mit Java-Bytecode zu schreiben.

2) CIL wurde entwickelt, um sich einfach in native Bibliotheken und nicht verwalteten Code zu integrieren

3) Java-Bytecode wurde entworfen, um entweder interpretiert oder kompiliert zu werden, während CIL nur unter der Annahme einer JIT-Kompilierung entworfen wurde. Das heißt, die anfängliche Implementierung von Mono verwendet einen Dolmetscher anstelle eines JIT.

4) CIL wurde entwickelt (und angegeben), um ein für Menschen lesbares und beschreibbares Assemblersprachenformular zu haben, das direkt dem Bytecode-Formular zugeordnet ist. Ich glaube, dass Java-Bytecode (wie der Name schon sagt) nur maschinenlesbar sein sollte. Natürlich lässt sich Java-Bytecode relativ einfach wieder in das ursprüngliche Java dekompilieren und, wie unten gezeigt, auch „disassemblieren“.

Ich sollte beachten, dass die JVM (die meisten von ihnen) stärker optimiert ist als die CLR (jede von ihnen). Die reine Leistung könnte also ein Grund sein, lieber auf Java-Bytecode abzuzielen. Dies ist jedoch ein Implementierungsdetail.

Einige Leute sagen, dass der Java-Bytecode für mehrere Plattformen entwickelt wurde, während CIL nur für Windows entwickelt wurde. Das ist nicht der Fall. Es gibt einige “Windows”ismen im .NET-Framework, aber keine in CIL.

Als Beispiel für Punkt 4) oben habe ich vor einiger Zeit einen Spielzeug-Java-to-CIL-Compiler geschrieben. Wenn Sie diesen Compiler mit dem folgenden Java-Programm füttern:

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 ;
    }
}

Mein Compiler spuckt die folgende CIL aus:

.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
   }
}

Dies ist ein gültiges CIL-Programm, das in einen CIL-Assembler wie eingespeist werden kann ilasm.exe um eine ausführbare Datei zu erstellen. Wie Sie sehen können, ist CIL eine vollständig vom Menschen lesbare und beschreibbare Sprache. Sie können problemlos gültige CIL-Programme in jedem Texteditor erstellen.

Sie können das obige Java-Programm auch mit kompilieren javac Compiler und führen Sie dann die resultierenden Klassendateien durch den javap “disassembler”, um Folgendes zu erhalten:

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
}

Das javap Die Ausgabe ist (meines Wissens) nicht kompilierbar, aber wenn Sie sie mit der CIL-Ausgabe oben vergleichen, können Sie sehen, dass die beiden sehr ähnlich sind.

  • Es stellt sich heraus, dass es Versuche gab, eine für Menschen lesbare/beschreibbare Java-Assemblersprache zu erstellen. Zwei, die ich gefunden habe, sind Jasmin und Java-Bytecode-Assembler

    – Justin

    20. Februar 2012 um 18:56 Uhr

  • Ich habe hier einen geschrieben, der viel besser ist. Im Gegensatz zu Jasmin ist es so konzipiert, dass es jede gültige Klassendatei zerlegen und wieder zusammensetzen kann. github.com/Storyyeller/Krakatau. Ich denke, es wäre genauer zu sagen, dass Microsoft einen Standard-Assembler bereitstellt, während Java-Codierer ihren eigenen erstellen müssen.

    – Antimon

    8. Mai 2013 um 17:43 Uhr


Benutzer-Avatar
Guy Starbuck

Sie tun im Wesentlichen dasselbe, MSIL ist Microsofts Version von Java-Bytecode.

Die Hauptunterschiede intern sind:

  1. Bytecode wurde sowohl für die Kompilierung als auch für die Interpretation entwickelt, während MSIL explizit für die JIT-Kompilierung entwickelt wurde
  2. MSIL wurde entwickelt, um mehrere Sprachen (C# und VB.NET usw.) zu unterstützen, anstatt dass Bytecode nur für Java geschrieben wird, was dazu führt, dass Bytecode Java syntaktisch ähnlicher ist als IL einer bestimmten .NET-Sprache
  3. MSIL hat eine explizitere Abgrenzung zwischen Wert- und Referenztypen

Viele weitere Informationen und einen ausführlichen Vergleich finden Sie in dieser Artikel von K. John Gough (Postscript-Dokument)

  • “1.Bytecode wurde sowohl für die Kompilierung als auch für die Interpretation entwickelt, während MSIL explizit für die JIT-Kompilierung entwickelt wurde” – Hier wird darüber gesprochen, wie Java-Code in Bytecode kompiliert UND dieser Bytecode interpretiert wird. Hab ich recht? Wird MSIL nicht interpretiert, um ausgeführt zu werden?

    – Honinbo Shusaku

    16. August 2016 um 18:54 Uhr

CIL alias MSIL soll für Menschen lesbar sein. Java-Bytecode ist es nicht.

Stellen Sie sich Java-Bytecode als Maschinencode für Hardware vor, die nicht existiert (aber von JVMs emuliert wird).

CIL ist eher wie Assemblersprache – einen Schritt vom Maschinencode entfernt, während es immer noch für Menschen lesbar ist.

Serge Lidin hat ein anständiges Buch über die Details von MSIL verfasst: Expert .NET 2.0 IL Assembler. Ich konnte MSIL auch schnell lernen, indem ich mir einfache Methoden ansah .NET-Reflektor und Ildasmus (Tutorial).

Die Konzepte zwischen MSIL und Java-Bytecode sind sehr ähnlich.

Da gibt es nicht so viele Unterschiede. Beides sind Zwischenformate des von Ihnen geschriebenen Codes. Bei der Ausführung führen die virtuellen Maschinen die verwaltete Zwischensprache aus, was bedeutet, dass die virtuelle Maschine die Variablen und Aufrufe steuert. Es gibt sogar eine Sprache, an die ich mich gerade nicht erinnere, die auf .Net und Java auf die gleiche Weise ausgeführt werden kann.

Im Grunde ist es nur ein anderes Format für dasselbe

Bearbeiten: Sprache gefunden (außer Scala): Es ist FAN (http://www.fandev.org/), sieht sehr interessant aus, aber noch keine Zeit zum Auswerten

Benutzer-Avatar
Internet-Freund

Zugegeben, die Unterschiede sind winzig genug, um sie als Anfänger zu ignorieren. Wenn Sie .Net von Grund auf lernen möchten, empfehle ich Ihnen, sich die Common Language Infrastructure und das Common Type System anzusehen.

1228610cookie-checkUnterschiede zwischen MSIL und Java-Bytecode?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy