Виртуальная машина Java и среда CLR
как своего рода продолжение вопроса, называемого различиями между MSIL и байт-кодом Java?, каковы (основные) различия или сходство в том, как работает виртуальная машина Java по сравнению с тем, как.NET Framework Common Language Runtime (CLR) работает?
кроме того, это .NET framework CLR "виртуальная машина" или она не имеет атрибутов виртуальной машины?
5 ответов:
есть много общего между обеими реализациями (и на мой взгляд: да, они оба "виртуальные машины").
во-первых, они оба стековые виртуальные машины, без понятия "регистры", как мы привыкли видеть в современном процессоре, таком как x86 или PowerPC. Оценка всех выражений ((1 + 1) / 2) выполняется путем нажатия операндов на "стек", а затем выталкивания этих операндов из стека всякий раз, когда инструкция (add, divide и т. д.) должна потреблять эти операнды. Каждая команда помещает его обратно в стек.
Это удобный способ реализации виртуальной машины, потому что почти каждый процессор в мире имеет стек, но количество регистров часто отличается (и некоторые регистры являются специальными, и каждая инструкция ожидает свои операнды в разных регистрах и т. д.).
Итак, если вы собираетесь моделировать абстрактную машину, чисто стековая модель-это довольно хороший способ идти.
конечно, настоящие машины так не работают. Таким образом, JIT-компилятор отвечает за выполнение "регистрации" операций байт-кода, по существу планируя фактические регистры ЦП, чтобы содержать операнды и результаты, когда это возможно.
Итак, я думаю, что это одна из самых больших общих черт между CLR и JVM.
Что касается отличий...
одно интересное различие между двумя реализациями заключается в том, что среда CLR включает инструкции по созданию универсальных типов, а затем по применению параметрических специализаций к этим типам. Таким образом, во время выполнения среда CLR считает List
совершенно отличным типом от List . под обложками он использует один и тот же MSIL для всех специализаций ссылочного типа (поэтому List
использует ту же реализацию, что и List в Java универсальные типы-это чисто трюк компилятора. JVM не имеет понятия о том, какие классы имеют аргументы типа, и он не может выполнять параметрические специализации во время выполнения.
с практической точки зрения это означает, что вы не можете перегружать методы Java на универсальных типах. У вас не может быть двух разных методов с одинаковым именем, отличающихся только тем, принимают ли они List
или List . Конечно, так как среда CLR знает о параметрических типах, у нее нет проблем с методами обработки, перегруженными специализациями универсального типа. на ежедневной основе, это разница, которую я замечаю больше всего между CLR и виртуальная машина Java.
другие важные различия включают в себя:
среда CLR имеет замыкания (реализованные как делегаты C#). JVM поддерживает закрытие только с Java 8.
среда CLR имеет сопрограммы (реализованные с помощью В C# 'выход' ключевое слово). СПМ этого не делает.
среда CLR позволяет коду пользователя определять новые типы значений (структуры), в то время как JVM предоставляет фиксированную коллекцию типов значений (byte, short, int, long, float, double, char, boolean) и позволяет пользователям определять только новые ссылочные типы (классы).
среда CLR поддерживает объявление и управление указателями. Это особенно интересно, потому что как JVM, так и CLR используют строгие реализация сборщика мусора с уплотнением поколений как их стратегия управления памятью. В обычных условиях строгое сжатие GC имеет очень трудное время с указателями, потому что при перемещении значения из одного места памяти в другое все указатели (и указатели на указатели) становятся недействительными. Но среда CLR предоставляет механизм "закрепления", чтобы разработчики могли объявить блок кода, в котором среда CLR не может перемещать определенные указатели. Это очень удобный.
самая большая единица кода в JVM - это либо "пакет", о чем свидетельствует ключевое слово "protected", либо, возможно, JAR (т. е. архив Java), о чем свидетельствует возможность указать jar в пути к классам и обработать его как папку кода. В среде CLR классы агрегируются в "сборки", и среда CLR предоставляет логику для рассуждений о сборках и управления ими (которые загружаются в "Домены приложений", предоставляя песочницы уровня подприложений для выделение памяти и выполнение кода).
формат байт-кода CLR (состоящий из инструкций MSIL и метаданных) имеет меньше типов инструкций, чем JVM. В JVM каждая уникальная операция (добавление двух значений int, добавление двух значений float и т. д.) имеет свою собственную уникальную инструкцию. В среде CLR все инструкции MSIL являются полиморфными (добавьте два значения), а JIT-компилятор отвечает за определение типов операндов и создание соответствующего машинного кода. Я не однако знайте, какая стратегия предпочтительнее. У обоих есть компромиссы. JIT-компилятор HotSpot для JVM может использовать более простой механизм генерации кода (ему не нужно определять типы операндов, потому что они уже закодированы в инструкции), но это означает, что ему нужен более сложный формат байт-кода с большим количеством типов команд.
Я использую Java (и восхищаюсь JVM) уже около десяти лет.
но, на мой взгляд, CLR теперь является превосходная реализация, почти во всех отношениях.
ваш первый вопрос заключается в сравнении 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 МБ. СПМ выделит дополнительно 50 МБ из операционная система. Как только код приложения перестанет использовать эту память, он будет собран мусор, и размер кучи JVM уменьшится. Однако JVM освободит только выделенную память операционной системы под определенным очень конкретных обстоятельствах. В противном случае в течение оставшегося времени жизни процесса эта память будет оставаться выделенной.
среда CLR, с другой стороны, освобождает выделенную память обратно в операционную систему, если она больше не нужна. В приведенном выше примере, среда CLR освободила бы память, как только куча уменьшилась.
более подробную информацию о различиях можно найти в различных академических и частных источниках. Когда-то хорошим примером является выбор дизайна среды CLR.
некоторые конкретные примеры включают в себя:
- некоторые низкоуровневые opperands типизируются, например "add two ints", где в качестве CLR используется полиморфный операнд. (т. е. fadd/iadd / ladd vs просто добавить)
- в настоящее время JVM выполняет более агрессивное профилирование и оптимизацию времени выполнения (т. е. Hotspot). В настоящее время среда CLR JIT-компилятором оптимизация, но не оптимизация времени выполнения (т. е. замена кода во время выполнения).
- CLR не встроенные виртуальные методы, JVM делает...
- поддержка типов значений в среде CLR за пределами только "примитивов".
среда CLR и JVM являются виртуальными машинами.
платформа .NET Framework и среда выполнения Java представляют собой пакет соответствующих виртуальных машин и их библиотек. Без библиотек виртуальные машины довольно бесполезны.
Это не виртуальная машина, .net framework компилирует сборки в собственный двоичный файл во время первого запуска:
в вычислительной технике JIT-компиляция (JIT), также известная как динамический перевод, является методом повышения производительности выполнения компьютерной программы. JIT основывается на двух более ранних идеях в средах выполнения: компиляция байт-кода и динамическая компиляция. Он преобразует код во время выполнения до его выполнения в собственном коде, например байт-код в машинный код. Повышение производительности по сравнению с интерпретаторами происходит от кэширования результатов перевода блоков кода, а не просто переоценки каждой строки или операнда каждый раз, когда он встречается (см. интерпретируемый язык). Он также имеет преимущества перед статической компиляцией кода во время разработки, поскольку он может перекомпилировать код, если это окажется выгодным, и может обеспечить гарантии безопасности. Таким образом, JIT может сочетать в себе некоторые преимущества интерпретации и статики (заранее) компиляция.
несколько современных сред выполнения, таких как Microsoft .NET Framework, большинство реализаций Java и совсем недавно Actionscript 3, полагаются на JIT-компиляцию для высокоскоростного выполнения кода.
Источник:http://en.wikipedia.org/wiki/Just-in-time_compilation
добавление .NET framework содержит виртуальную машину, как и Java.