Введение

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

Сравнение виртуальных машин

JavaScript-машины не включены. См. Список движков ECMAScript, чтобы найти их. Таблица здесь суммирует элементы, для которых конструкции виртуальных машин должны быть эффективными, а не перечень возможностей, присутствующих в любой реализации. Виртуальная машинаМодель машиныУправление памятьюБезопасность кодаИнтерпретаторJITАОТОбщие библиотекиОбщая объектная модельCommon Language Object ModelДинамическая типизацияAndroid Runtime (ART) регистр автоматическийCommon Language Runtime (CLR) стек автоматический или ручнойDis (Inferno) регистр автоматическийDotGNU Portable. NET стек автоматический или ручнойJava Virtual Machine (JVM) стек автоматический ✔JikesRVM стек автоматическийLLVM регистр ручнойMono стек автоматический или ручнойParrot регистр автоматическийDalvik регистр автоматическийSqueak стек автоматическийBEAM (Erlang) регистр автоматическийMoarVM регистр автоматический

Инструкции виртуальной машины обрабатывают данные в локальных переменных, используя основную модель вычислений, как правило, модель стековой машины, регистровой машины или машины с произвольным доступом к памяти, часто называемую машиной памяти. Использование этих трех методов обусловлено различными компромиссами между виртуальными и физическими машинами, такими как простота интерпретации, компиляции и проверки безопасности. Управление памятью в этих переносимых виртуальных машинах осуществляется на более высоком уровне абстракции, чем в физических машинах. Некоторые виртуальные машины, такие как популярные Java Virtual Machines (JVM), взаимодействуют с адресами таким образом, что требуют безопасного автоматического управления памятью, позволяя виртуальной машине отслеживать ссылки на указатели и запрещать машинным инструкциям вручную создавать указатели в память. Другие виртуальные машины, такие как LLVM, больше похожи на традиционные физические машины, позволяя прямое использование и манипулирование указателями. Common Intermediate Language (CIL) предлагает гибридный подход, позволяя как контролируемое использование памяти (как в JVM, обеспечивающей безопасное автоматическое управление памятью), так и "небезопасный" режим, который позволяет прямое манипулирование указателями способами, которые могут нарушать границы типов и разрешения. Безопасность кода обычно относится к способности переносимой виртуальной машины запускать код, предоставляя ей только предписанный набор возможностей. Например, виртуальная машина может разрешить коду доступ только к определенному набору функций или данных. Те же средства контроля над указателями, которые обеспечивают автоматическое управление памятью и позволяют виртуальной машине гарантировать типобезопасный доступ к данным, используются для обеспечения того, чтобы фрагмент кода имел доступ только к определенным элементам памяти и не мог обходить саму виртуальную машину. Другие механизмы безопасности затем добавляются поверх, такие как верификаторы кода, верификаторы стека и другие методы. Интерпретатор позволяет загружать и запускать программы, состоящие из виртуальных инструкций, без потенциально дорогостоящей компиляции в машинные инструкции. Любую виртуальную машину можно интерпретировать, поэтому обозначение столбца здесь относится к тому, включает ли конструкция положения для эффективной интерпретации (для общего использования). Компиляция "точно в срок" (JIT) относится к методу компиляции в машинные инструкции в самый последний момент, обычно непосредственно перед или во время выполнения программы. Сложность JIT заключается скорее в реализации, чем в проектировании виртуальной машины, однако современные конструкции начали учитывать факторы, способствующие повышению эффективности. Самые простые методы JIT просто компилируют фрагмент кода, аналогичный оффлайн-компилятору. Однако часто используются более сложные методы, которые специализируют скомпилированные фрагменты кода на параметрах, известных только во время выполнения (см. Адаптивная оптимизация). Компиляция заранее (AOT) относится к более классическому методу использования прекомпилятора для генерации набора машинных инструкций, которые не изменяются во время выполнения программы. Поскольку агрессивная компиляция и оптимизация могут занимать время, предварительно скомпилированная программа может запускаться быстрее, чем та, которая полагается только на JIT для выполнения. Реализации JVM смягчили эту стоимость запуска, сначала используя интерпретацию для ускорения времени запуска, пока не будут сгенерированы фрагменты машинного кода с помощью JIT. Общие библиотеки — это средство повторного использования сегментов машинного кода между несколькими запущенными программами. В современных операционных системах это обычно означает использование виртуальной памяти для совместного использования страниц памяти, содержащих общую библиотеку, между различными процессами, которые защищены друг от друга с помощью защиты памяти. Интересно, что агрессивные методы JIT, такие как адаптивная оптимизация, часто создают фрагменты кода, непригодные для совместного использования между процессами или последовательными запусками программы, что требует компромисса между эффективностью предварительно скомпилированного и совместно используемого кода и преимуществами адаптивно специализированного кода. Например, несколько конструктивных положений CIL предназначены для обеспечения эффективных общих библиотек, возможно, за счет более специализированного JIT-кода. Реализация JVM на OS X использует Java Shared Archive для обеспечения некоторых преимуществ общих библиотек.

Сравнение приложений в реализациях виртуальных машин

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

Языки виртуальных машин | Комментарии | Интерпретатор | JIT | Язык реализации | SLoC
---|---|---|---|---|---
Common Language Runtime (CLR) | C#, C++/CLI, F#, VB. NET; байт-код CIL; NET Core Runtime на GitHub | | | C#, C++ |
Adobe Flash Player (также известный как Tamarin) | ActionScript, SWF (формат файла); интерактивный инструмент для веб-разработки. Байт-код называется "ActionScript Byte Code (.abc)" | | | C++ | 135k (первоначально выпущен)
Dis (Inferno) | Limbo Dis Virtual Machine Specification | | | C | 15k + 2850 на JIT архитектуру + 500 на хост OS
DotGNU Portable. NET | CLI языки, включая: C#; Common Language Runtime clone | | | C, C# |
Forth | Функции упрощены, обычно включают ассемблер, компилятор, интерпретаторы текстового и бинарного уровней, иногда редактор, отладчик и ОС. Скорость компиляции >20 SKLOC/S и поведение аналогично JIT. | | | Forth, Forth Assembler | 2.8K - 5.6K; продвинутые, профессиональные реализации меньше.
Glulx | Inform 6, Inform 7, другие | Различные реализации существуют | | |
HHVM | PHP, Hack; виртуальная машина с открытым исходным кодом для выполнения программ, написанных на Hack и PHP. | | | C++, OCaml |
Icon | Base предоставляет как интерпретатор, так и неподдерживаемую компиляцию в C. Код времени выполнения, используемый компилятором и интерпретатором, написан на варианте C, называемом RTT. | | | C, RTT (специализированный интерфейс для C, поставляемый с базовым исходным кодом Icon) | ~180k (исходник в байт-код: ~11k, интерпретатор байт-кода: ~46k, iconc: ~23k, common/headers: ~13k, rtt: ~15k)
JVM | Java, Kotlin, Jython, Groovy, JRuby, C, C++, Clojure, Scala и другие; референсная реализация Sun; OpenJDK: код под GPL; IcedTea: код и инструменты под GPL | | | JDK, OpenJDK & IcedTea с обычным JIT: Java, C, C++, ASM; IcedTea с "Zero" JIT: Java, C, C++ | ~6500k строк; TCK: 80k тестов и ~1000k строк
LLVM | C, C++, Kotlin, Objective C, Swift, Ada, Fortran, Rust; поддерживаются MSIL, C и C++ выходные данные. Поддержка вывода байт-кода ActionScript через Adobe Alchemy. Байт-код называется "LLVM Bytecode (.bc)". Ассемблерный код называется "LLVM Assembly Language (*.ll)". | | | C++ | 811k
Lua | | LuaJIT | | C | 13k + 7k LuaJIT
MMIX | MMIXAL | | | |
Mono | CLI языки, включая: C#, VB. NET, IronPython, IronRuby и другие; Common Language Runtime clone | | | C#, C | 2332k
NekoVM | Neko и Haxe | | | C | 46k (только x86)
Oz | Oz, Alice | | | |
Pascal | UCSD Pascal, широко распространенный в конце 70-х, включая Apple II assembly | | | |
Parrot | Perl 5, Raku, NQP; rx, PIR, PASM, PBC, BASIC, bc, C99, ECMAScript, Lisp, Lua, m4, Tcl, WMLScript, XML и другие | | | C, Perl | 111k C, 240k Perl
Perl virtual machine | Perl op code tree walker | | | C, Perl | 175k C, 9k Perl
CPython | Python | Psyco, Unladen Swallow | | C | 387k C, 368k Python, 10k ASM, 31k Psyco
PyPy | Python; самохостинг реализация Python, следующее поколение Psyco | | | Python |
Rubinius | Ruby; виртуальная машина для другой реализации Ruby | | | C++, Ruby |
Silverlight | C#, VB. NET; микроверсия Microsoft .NET Framework для запуска приложений в изолированной среде браузера | | | C++ | 7MB (первоначально выпущен)
ScummVM | Scumm; компьютерный игровой движок | | | |
SECD | ISWIM, Lispkit Lisp | | | |
Squirrel | Squirrel; Squirrel JIT | | | C++ | 12k
Smalltalk | Smalltalk | | | |
SQLite | SQLite opcodes; виртуальный движок базы данных | | | |
Squeak | Squeak Smalltalk; самохостинг реализация виртуальной машины Squeak. Богатая мультимедийная поддержка. | | | Smalltalk | 110k Smalltalk, ~300K
CSWI | PrologProlog: SWI Prolog, YAP | | | C, SWI Prolog |
TraceMonkey | JavaScript; на основе Tamarin | | | C++ | 173k
TrueType | TrueType; движок рендеринга шрифтов | | | C (обычно) |
Valgrind | x86/x86 64 бинарные файлы; проверка доступа к памяти и утечек под Linux | | | C | 467k
VisualWorks Smalltalk | | | | C |
Vx32 virtual machine | x86 бинарные файлы; виртуализация на уровне приложения для нативного кода | | | |
Waba | Виртуальная машина для небольших устройств, аналогичная Java | | | |
Yet Another Ruby VM (YARV) | Ruby; виртуальная машина референсной реализации для Ruby 1.9 и более новых версий | | | C |
Z machine | Z Code | | | |
Zend Engine | PHP | | | C | 75k