Frage

Als eine Art folgen bis zu der Frage Unterschiede zwischen MSIL und Java-Bytecode genannt? , was die (großen) Unterschiede oder Ähnlichkeiten, wie die Java Virtual Machine arbeitet im Vergleich zu, wie die .NET Framework Common Language Runtime (CLR) funktioniert?

Auch ist die .NET Framework CLR eine „virtuelle Maschine“ oder hat er nicht die Eigenschaften einer virtuellen Maschine?

War es hilfreich?

Lösung

Es gibt viele Ähnlichkeiten zwischen den beiden Implementierungen (und meiner Meinung nach: Ja, sie sind beide „virtuelle Maschinen“).

Für eine Sache, sie sind beide Stack-basierten VM, ohne Begriff „Register“ wie wir zu sehen in einer modernen CPU wie die x86 oder PowerPC gewohnt sind. Die Auswertung aller Ausdrücke ((1 + 1) / 2) wird durch Drücken Operanden auf den „Stapel“ durchgeführt und dann die Operanden vom Stapel knallten, wenn eine Anweisung (hinzufügen, divide, etc.), um diese Operanden verbrauchen muss. Jeder Befehl schiebt seine Ergebnisse zurück auf den Stapel.

Es ist ein bequemer Weg, um eine virtuelle Maschine zu implementieren, weil so ziemlich jede CPU in der Welt einen Stapel hat, aber die Anzahl von Registern ist oft unterschiedlich (und einige Register sind für besondere Zwecke, und jeder Befehl erwartet seine Operanden in verschiedenen Register usw.).

Wenn Sie also eine abstrakte Maschine zu modellieren gehen, ein rein Stack-basiertes Modell ist ein ziemlich guter Weg zu gehen.

Natürlich reale Maschinen arbeiten nicht auf diese Weise. So ist der JIT-Compiler ist verantwortlich für die Durchführung von „enregistration“ von Bytecode-Operationen, im Wesentlichen plant die tatsächliche CPU-Register Operanden und Ergebnisse enthalten, wenn möglich.

So

, ich denke, das ist einer der größten Gemeinsamkeiten zwischen der CLR und die JVM.

Wie für Unterschiede ...

Ein interessanter Unterschied zwischen den beiden Implementierungen ist, dass die CLR Anweisungen generische Typen für die Erstellung enthält, und dann für parametrische Spezialisierungen auf diese Art der Anwendung. Also, zur Laufzeit hält die CLR eine List eine ganz andere Art von einer List sein.

Unter den Abdeckungen, verwendet es die gleiche MSIL für alle Referenztyp Spezialisierungen (so eine List verwendet die gleiche Implementierung als List , mit verschiedenem Typ wirft an den API-Grenzen), aber jeder Wert -Typ verwendet seine eigene einzigartige Implementierung (List erzeugt völlig anderen Code von List ).

In Java generische Typen sind ein rein Compiler-Trick. Die JVM hat keine Ahnung, welche Klassen Typ-Argumente haben, und es ist nicht in der Lage parametrische Spezialisierungen zur Laufzeit auszuführen.

Aus praktischer Sicht, das heißt, Sie nicht Java-Methoden auf generische Typen überlasten können. Sie können nicht zwei verschiedene Methoden, mit dem gleichen Namen, die sich nur, ob sie eine List oder eine List akzeptieren. Natürlich, da Typen kennt die CLR über parametrisch, es kein Problem Methoden überlastet auf generische Art Spezialisierungen hat Handhabung.

An einem Tag zu Tag, das ist der Unterschied, dass ich die meisten bemerken zwischen der CLR und der JVM.

Weitere wichtige Unterschiede sind:

  • Die CLR hat Verschlüsse (implementiert als C # Delegierten). Die JVM unterstützt jedoch Schließungen nur da Java 8.

  • Die CLR hat Koroutinen (mit C # 'Ausbeute' Schlüsselwort implementiert). Die JVM nicht.

  • Der CLR ermöglicht user neuen Wert-Typen (Strukturen) zu definieren, während die JVM eine feste Sammlung von Werttypen liefert (Byte, short, int, lang, float, double, char, boolean), und nur erlaubt Benutzer neue Referenz-Typen (Klassen) zu definieren.

  • Die CLR bietet Unterstützung für die Erklärung und die Manipulation Zeiger. Dies ist besonders interessant, weil sowohl die JVM und die CLR strenge Garbage-Collector-Implementierungen als ihre Speicher-Management-Strategie Generationenverdichtung einzusetzen. Unter normalen Umständen hat eine strenge Verdichtung GC eine wirklich harte Zeit mit Zeigern, denn wenn man einen Wert von einem Speicherort zu einem anderen verschieben, alle Zeiger (und Zeiger auf Zeiger) ungültig. Aber die CLR einen „Pinning“ Mechanismus, so dass Entwickler einen Code-Block deklarieren können, innerhalb dem die CLR nicht erlaubt ist, bestimmten Zeiger zu bewegen. Es ist sehr bequem.

  • Die größte Codeeinheit in der JVM ist entweder ein ‚Paket‘, wie durch das ‚geschützte‘ Schlüsselwort belegte oder wohl eine JAR (d Java ARcBienenstock), wie sie in der Lage, belegte ein Glas in der Classpath specifiy und hat es wie ein Ordner von Code behandelt. In der CLR werden Klassen in ‚Baugruppen‘ aggregiert und die CLR liefern Logik zum Nachdenken über und Manipulieren von Baugruppen (die in „AppDomains“ geladen werden, Teilanwendungsebene Sandkästen für die Speicherzuordnung und die Ausführung von Code bereitstellt).

  • Das CLR-Bytecode-Format (bestehend aus MSIL Anweisungen und Metadaten) hat wenige Befehlstypen als die JVM. In der JVM hat jede einzigartige Operation (fügen Sie zwei int-Werte, fügen Sie zwei Float-Werte, usw.) seinen eigenen Unterricht. In der CLR, sind alle der MSIL Anweisungen polymorpher (fügen zwei Werte) und der JIT-Compiler ist für die Typen der Operanden zu bestimmen und entsprechenden Maschinencode erzeugt wird. Ich weiß nicht, was die vorzugsweise Strategie ist, though. Beide haben Kompromisse. Die HotSpot JIT-Compiler für die JVM können einen einfacheren Code-Erzeugungsmechanismus zu verwenden (es ist nicht Operandentypen zu bestimmen, benötigt, da sie bereits in dem Befehl codiert sind), aber das bedeutet, dass es ein komplexere Bytecode-Format benötigt, mit mehr Befehlstypen.

Ich habe Java unter Verwendung von (und die JVM bewundern) jetzt seit etwa zehn Jahren.

Aber meiner Meinung nach ist die CLR ist jetzt die bessere Umsetzung, in fast jeder Hinsicht.

Andere Tipps

Ihre erste Frage ist die JVM mit dem .NET Framework zu vergleichen - ich nehme an, Sie tatsächlich stattdessen mit der CLR vergleichen gemeint. Wenn ja, ich glaube, Sie ein kleines Buch zu diesem Thema schreiben können ( EDIT: sieht aus wie schon Benji hat :-)

Ein wichtiger Unterschied ist, dass die CLR ist so konzipiert, eine sprachneutrale Architektur zu sein, im Gegensatz zu der JVM.

Ein weiterer wichtiger Unterschied ist, dass der CLR speziell für ein hohes Maß an Interoperabilität ausgelegt wurde mit nativen Code zu ermöglichen. Dies bedeutet, dass die CLR Zuverlässigkeit und Sicherheit verwalten müssen, wenn nativen Speicher zugegriffen wird und verändert, und auch sehr zurückhaltend freizugeben zugewiesenen Speicher wieder an das Betriebssystem, auch dort, wo er kann.

Zum Beispiel, sagen wir mal, dass ein JVM-Prozess beginnt und weist 25 MB Arbeitsspeicher vom Betriebssystem zunächst. Der App-Code versucht dann, Zuweisungen, die weiteren 50 MB erforderlich. Die JVM wird weitere 50 MB vom Betriebssystem zuordnen. Sobald der Anwendungscode hat die Verwendung dieses Speichers gestoppt wird, ist es Garbage Collection und die JVM-Heap-Größe zu verringern. Allerdings wird die JVM nur Freigabe des verwendeten Betriebssystemspeicher unter bestimmten ganz bestimmten Umständen . Ansonsten für den Rest des Prozesses Lebensdauer, dass der Speicher zugeordnet bleiben.

Die CLR, auf der anderen Seite, Mitteilungen Speicher zurück an das Betriebssystem zugeordnet, wenn es nicht mehr benötigt wird. In dem obigen Beispiel wäre der CLR freigegeben den Speicher, sobald der Haufen abgenommen hatte.

Weitere Einzelheiten über die Unterschiede können aus verschiedenen akademischen und privaten Quellen. Sobald gutes Beispiel dafür ist CLR Design-Auswahl .

Einige spezifische Beispiele schließen ein:

  • Einig Low-Level-opperands ist typisiert wie „add zwei ints“, wo als CLR einen polymorphen Operanden verwendet. (D FADD / iadd / ladd vs nur hinzufügen)
  • Derzeit ist die JVM macht mehr aggresive Laufzeitprofilierung und Optimierung (das heißt Hotspot). CLR funktioniert derzeit JIT-Optimierungen, aber nicht Optimierung Laufzeit (das heißt Code ersetzen, während Sie laufen).
  • CLR nicht inline nicht virtuelle Methoden, JVM tut ...
  • Unterstützung für Werttypen in der CLR mehr als nur die "Primitiven".

Die CLR und die JVM sind beide virtuellen Maschinen.

Das .NET Framework und die Java Runtime Environment ist die Bündelung der jeweiligen VMs und die Bibliotheken. Ohne Bibliotheken sind die VMs ziemlich nutzlos.

Es ist nicht eine virtuelle Maschine, die .net Framework zum Zeitpunkt des ersten Laufes der Baugruppen in native binary kompiliert:

In der Computersprache, Just-in-Time-Kompilierung (JIT), auch als dynamische Übersetzung bekannt, ist eine Technik zur Verbesserung der Laufzeitleistung eines Computerprogrammes. JIT baut auf zwei früheren Ideen in Laufzeitumgebungen: Bytecode-Zusammenstellung und dynamische Kompilierung. Er wandelt Code zur Laufzeit, bevor es die Ausführung zum Beispiel Bytecode in Maschinencode nativ. Die Leistungsverbesserung gegenüber Dolmetschern stammt von Zwischenspeichern, die Ergebnisse von Blöcken von Code zu übersetzen, und nicht einfach jede Zeile oder jedes Mal neu zu bewerten Operanden es erfüllt ist (siehe interpretierte Sprache). Es hat auch Vorteile gegenüber statisch den Code zur Entwicklungszeit kompilieren, da sie den Code neu kompilieren können, wenn dies vorteilhaft erwiesen ist, und können Sicherheitsgarantien erzwingen kann. So JIT können einige der Vorteile der Interpretation und statischen (Voraus-Zeit) Zusammenstellung kombinieren.

Einige moderne Laufzeitumgebungen wie Microsoft .NET Framework, die meisten Implementierungen von Java und seit neuestem Actionscript 3, die sich auf JIT-Kompilierung für High-Speed-Ausführung von Code.

Quelle: http://en.wikipedia.org/wiki/Just-in -time_compilation

Hinzufügen von .NET-Framework enthält eine virtuelle Maschine, so wie Java.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top