Виртуальная машина Java и CLR - программирование

Виртуальная машина Java и CLR

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

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

4b9b3361

Ответ 1

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

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

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

Итак, если вы собираетесь моделировать абстрактную машину, для нее может использоваться довольно простая модель на основе стека.

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

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

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

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

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

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

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

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

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

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

  • CLR имеет сопрограммы (реализованы с ключевым словом С# 'yield'). JVM не делает.

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

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

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

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

Я использую Java (и любуюсь JVM) около десяти лет.

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

Ответ 2

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

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

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

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

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

Итак, педантичный ответ на ваш второй вопрос "нет". Но это действительно сводится к тому, как вы определяете эти два термина.

EDIT: Еще одно отличие между JVM и CLR заключается в том, что JVM (версия 6) очень неохотно освобождает выделенную память обратно в операционную систему, даже там, где это возможно.

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

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

Ответ 3

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

.NET Framework и среда выполнения Java - это объединение соответствующих виртуальных машин и их библиотек. Без библиотек виртуальные машины довольно бесполезны.

Ответ 4

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

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

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

Ответ 5

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

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

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

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

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