Виртуальная машина Java и CLR - PullRequest
131 голосов
/ 17 января 2009

В качестве своего рода ответа на вопрос, называемый Различия между MSIL и Java-байт-кодом? , в чем (основные) различия или сходство в том, как работает виртуальная машина Java, и как . NET Framework Common Language Runtime (CLR) работает?

Кроме того, .NET framework CLR - это "виртуальная машина" или она не имеет атрибутов виртуальной машины?

Ответы [ 5 ]

271 голосов
/ 26 января 2009

Существует много общего между обеими реализациями (и, на мой взгляд, да, они обе "виртуальные машины").

С одной стороны, они обе являются виртуальными машинами на основе стека, без понятия «регистры», как мы привыкли видеть в современных процессорах, таких как x86 или PowerPC. Оценка всех выражений ((1 + 1) / 2) выполняется путем помещения операндов в «стек» и последующего извлечения этих операндов из стека, когда инструкция (сложение, деление и т. Д.) Должна использовать эти операнды. Каждая инструкция помещает свои результаты обратно в стек.

Это удобный способ реализации виртуальной машины, потому что почти каждый ЦП в мире имеет стек, но число регистров часто различается (и некоторые регистры имеют специальное назначение, и каждая инструкция ожидает свои операнды в разных регистры и т. д.).

Так что, если вы собираетесь моделировать абстрактную машину, то модель, основанная исключительно на стеках, - хороший путь.

Конечно, реальные машины не работают таким образом. Таким образом, JIT-компилятор отвечает за выполнение «регистрации» операций с байт-кодом, по существу, планируя фактические регистры ЦП, чтобы они по возможности содержали операнды и результаты.

Итак, я думаю, что это одно из самых больших сходств между CLR и JVM.

Что касается различий ...

Одно интересное различие между двумя реализациями состоит в том, что CLR включает инструкции для создания универсальных типов, а затем для применения параметрических специализаций к этим типам. Таким образом, во время выполнения CLR считает List совершенно другим типом из List .

Под прикрытием он использует один и тот же MSIL для всех специализаций ссылочного типа (таким образом, список использует ту же реализацию, что и список , с различными приведениями типов на границах API), но каждое значение -type использует собственную уникальную реализацию (List генерирует совершенно другой код из List ).

В Java универсальные типы - это чисто трюк с компилятором. JVM не имеет представления о том, какие классы имеют аргументы типа, и не может выполнять параметрические специализации во время выполнения.

С практической точки зрения это означает, что вы не можете перегружать методы Java для универсальных типов. У вас не может быть двух разных методов с одинаковым именем, различающихся только тем, принимают ли они List или List . Конечно, поскольку CLR знает о параметрических типах, у него нет проблем с обработкой методов, перегруженных в специализациях универсальных типов.

В повседневной жизни я больше всего замечаю разницу между CLR и JVM.

Другие важные отличия включают в себя:

  • CLR имеет замыкания (реализовано как делегаты C #). JVM поддерживает замыкания только после Java 8.

  • В CLR есть сопрограммы (реализовано с помощью C # ключевого слова yield). JVM этого не делает.

  • CLR позволяет пользовательскому коду определять новые типы значений (структуры), тогда как JVM предоставляет фиксированный набор типов значений (байтовый, короткий, int, long, float, double, char, boolean) и разрешает только пользователи могут определять новые ссылочные типы (классы).

  • CLR поддерживает декларирование и манипулирование указателями. Это особенно интересно, потому что как JVM, так и CLR используют строгие реализации сжатия сборщиков мусора в качестве стратегии управления памятью. При обычных обстоятельствах строгому сжатию GC действительно трудно справиться с указателями, потому что при перемещении значения из одной ячейки памяти в другую все указатели (и указатели на указатели) становятся недействительными. Но CLR предоставляет механизм «закрепления», так что разработчики могут объявить блок кода, в котором CLR не разрешено перемещать определенные указатели. Это очень удобно.

  • Самая большая единица кода в JVM - это либо «пакет», о чем свидетельствует ключевое слово «защищенный», либо, возможно, JAR (то есть Java ARchive), что подтверждается возможностью указать jar в пути к классам и Рассматривать это как папку с кодом. В CLR классы объединяются в «сборки», а CLR предоставляет логику для рассуждения о сборках и манипулирования ими (которые загружаются в «домены приложений», предоставляя «песочницы» на уровне приложений для выделения памяти и выполнения кода).

  • Формат байт-кода CLR (составленный из инструкций и метаданных MSIL) имеет меньше типов инструкций, чем JVM. В JVM каждая уникальная операция (добавление двух значений int, добавление двух значений с плавающей запятой и т. Д.) Имеет собственную уникальную инструкцию. В CLR все инструкции MSIL являются полиморфными (добавьте два значения), и JIT-компилятор отвечает за определение типов операндов и создание соответствующего машинного кода. Хотя я не знаю, какая стратегия предпочтительнее. У обоих есть компромиссы. JIT-компилятор HotSpot для JVM может использовать более простой механизм генерации кода (ему не нужно определять типы операндов, потому что они уже закодированы в инструкции), но это означает, что ему нужен более сложный формат байт-кода, с большим количеством типов инструкций.

Я использую Java (и восхищаюсь JVM) уже около десяти лет.

Но, на мой взгляд, CLR теперь является превосходной реализацией почти во всех отношениях.

25 голосов
/ 17 января 2009

Ваш первый вопрос - сравнение JVM с .NET Framework - я полагаю, вы действительно вместо этого хотели сравнить с CLR. Если так, я думаю, вы могли бы написать небольшую книгу об этом ( РЕДАКТИРОВАТЬ: похоже, что Бенджи уже есть :-)

Одним из важных отличий является то, что CLR спроектирована как независимая от языка архитектура, в отличие от JVM.

Другое важное отличие заключается в том, что CLR был специально разработан для обеспечения высокого уровня взаимодействия с собственным кодом. Это означает, что CLR должен управлять надежностью и безопасностью при обращении к собственной памяти и ее изменении, а также управлять распределением между структурами данных на основе CLR и собственными структурами данных.

Чтобы ответить на ваш второй вопрос, термин «виртуальная машина» - это более старый термин из мира аппаратного обеспечения (например, виртуализация IBM 360-х в 1960-х годах), который использовался для обозначения программной / аппаратной эмуляции базовой машины для достижения цели. То же, что и VMWare.

CLR часто называют «механизмом исполнения». В этом контексте это реализация IL-машины поверх x86. Это также то, что делает JVM, хотя можно утверждать, что между полиморфными байт-кодами CLR и типизированными байт-кодами JVM есть важное различие.

Так что педантичный ответ на ваш второй вопрос - «нет». Но на самом деле все сводится к тому, как вы определяете эти два термина.

РЕДАКТИРОВАТЬ: Еще одно различие между JVM и CLR заключается в том, что JVM (версия 6) очень неохотно , чтобы освободить выделенную память обратно операционной системе, даже там, где Можно.

Например, предположим, что процесс JVM запускается и первоначально выделяет 25 МБ памяти из операционной системы. Затем код приложения пытается выделить ресурсы, которые требуют дополнительных 50 МБ. JVM выделит дополнительные 50 МБ из операционной системы. После того, как код приложения перестал использовать эту память, он будет собирать мусор, и размер кучи JVM уменьшится. Однако JVM освобождает выделенную память операционной системы только при определенных очень специфических обстоятельствах . В противном случае, до конца срока службы процесса эта память останется выделенной.

CLR, с другой стороны, освобождает выделенную память операционной системе, если она больше не нужна. В приведенном выше примере CLR освободил бы память после уменьшения кучи.

11 голосов
/ 28 января 2009

Более подробную информацию о различиях можно найти в различных научных и частных источниках. Один хороший пример: CLR Design Choices .

Некоторые конкретные примеры включают:

  • Некоторые операнды низкого уровня набираются, например, «добавить два целых», где в CLR используется полиморфный операнд. (то есть fadd / iadd / ladd vs просто добавьте)
  • В настоящее время JVM выполняет более агрессивные профилирование и оптимизацию во время выполнения (т. Е. Hotspot). В настоящее время CLR выполняет оптимизацию JIT, но не оптимизацию во время выполнения (т.е. заменяет код во время работы).
  • CLR не встроенные виртуальные методы, JVM делает ...
  • Поддержка типов значений в CLR, кроме "примитивов".
9 голосов
/ 17 января 2009

CLR и JVM являются виртуальными машинами.

.NET Framework и Java Runtime Environment представляют собой связку соответствующих ВМ и их библиотек. Без библиотек виртуальные машины бесполезны.

0 голосов
/ 17 января 2009

Это не виртуальная машина, платформа .net компилирует сборки в собственный двоичный файл во время первого запуска:

В вычислениях компиляция точно в срок (JIT), также известная как динамическая трансляция, представляет собой метод повышения производительности компьютерной программы во время выполнения. JIT опирается на две более ранние идеи в средах выполнения: компиляция байт-кода и динамическая компиляция. Он преобразует код во время выполнения до его естественного выполнения, например, байт-код в машинный код. Повышение производительности по сравнению с интерпретаторами происходит из-за кэширования результатов перевода блоков кода, а не просто переоценки каждой строки или операнда каждый раз, когда они встречаются (см. Интерпретированный язык). Он также имеет преимущества по сравнению со статической компиляцией кода во время разработки, так как он может перекомпилировать код, если это окажется полезным, и может быть в состоянии обеспечить гарантии безопасности. Таким образом, JIT может сочетать некоторые преимущества интерпретации и статической (опережающей) компиляции.

Некоторые современные среды выполнения, такие как Microsoft .NET Framework, большинство реализаций Java и последний ActionScript 3, используют JIT-компиляцию для высокоскоростного выполнения кода.

Источник: http://en.wikipedia.org/wiki/Just-in-time_compilation

Добавление .NET Framework содержит виртуальную машину, как и Java.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...