Comparison of application virtualization software

Last updated

Application virtualization software refers to both application virtual machines and software responsible for implementing them. Application virtual machines are typically used to allow application bytecode to run portably on many different computer architectures and operating systems. The application is usually run on the computer using an interpreter or just-in-time compilation (JIT). There are often several implementations of a given virtual machine, each covering a different set of functions.

Contents

Comparison of virtual machines

JavaScript machines not included. See List of ECMAScript engines to find them.

The table here summarizes elements for which the virtual machine designs are intended to be efficient, not the list of abilities present in any implementation.

Virtual machine Machine model Memory management Code security Interpreter JIT AOT Shared libraries Common Language Object Model Dynamic typing
Android Runtime (ART) register automaticYesYesYesYes?YesYes
Common Language Runtime (CLR) stack automatic or manualYesYesYesYesYesYesYes
Dis (Inferno) register automaticYesYesYesYesYesYesYes
DotGNU Portable.NET stack automatic or manualYesYesYesYesYesYesNo
Java virtual machine (JVM) stack automaticYesYesYesYesYesYesYes [1]
JikesRVM stack automaticYesYesYesYes?YesYes
LLVM register manualNoYesYesYesYesYesNo
Mono stack automatic or manualYesYesYesYesYesYesYes
Parrot register automaticNoYesNo [2] YesYesYesYes
Dalvik register automaticYesYesYesNo?NoNo
Squeak stack automaticNoYesYesNoYesNoYes
BEAM (Erlang) register automatic?YesYesYesYesYesYes
MoarVM register automatic?YesYesYesYesYesYes

Virtual machine instructions process data in local variables using a main model of computation , typically that of a stack machine, register machine, or random access machine often called the memory machine. Use of these three methods is motivated by different tradeoffs in virtual machines vs physical machines, such as ease of interpreting, compiling, and verifying for security.

Memory management in these portable virtual machines is addressed at a higher level of abstraction than in physical machines. Some virtual machines, such as the popular Java virtual machines (JVM), are involved with addresses in such a way as to require safe automatic memory management by allowing the virtual machine to trace pointer references, and disallow machine instructions from manually constructing pointers to memory. Other virtual machines, such as LLVM, are more like traditional physical machines, allowing direct use and manipulation of pointers. Common Intermediate Language (CIL) offers a hybrid in between, allowing both controlled use of memory (like the JVM, which allows safe automatic memory management), while also allowing an 'unsafe' mode that allows direct pointer manipulation in ways that can violate type boundaries and permission.

Code security generally refers to the ability of the portable virtual machine to run code while offering it only a prescribed set of abilities. For example, the virtual machine might only allow the code access to a certain set of functions or data. The same controls over pointers which make automatic memory management possible and allow the virtual machine to ensure typesafe data access are used to assure that a code fragment is only allowed to certain elements of memory and cannot bypass the virtual machine itself. Other security mechanisms are then layered on top as code verifiers, stack verifiers, and other methods.

An interpreter allows programs made of virtual instructions to be loaded and run immediately without a potentially costly compile into native machine instructions. Any virtual machine which can be run can be interpreted, so the column designation here refers to whether the design includes provisions for efficient interpreting (for common usage).

Just-in-time compilation (JIT), refers to a method of compiling to native instructions at the latest possible time, usually immediately before or during the running of the program. The challenge of JIT is more one of implementation than of virtual machine design, however, modern designs have begun to make considerations to help efficiency. The simplest JIT methods simply compile to a code fragment similar to an offline compiler. However, more complex methods are often employed, which specialize compiled code fragments to parameters known only at runtime (see Adaptive optimization).

Ahead-of-time compilation (AOT) refers to the more classic method of using a precompiler to generate a set of native instructions which do not change during the runtime of the program. Because aggressive compiling and optimizing can take time, a precompiled program may launch faster than one which relies on JIT alone for execution. JVM implementations have mitigated this startup cost by initial interpreting to speed launch times, until native code fragments can be generated by JIT.

Shared libraries are a facility to reuse segments of native code across multiple running programs. In modern operating systems, this generally means using virtual memory to share the memory pages containing a shared library across different processes which are protected from each other via memory protection. It is interesting that aggressive JIT methods such as adaptive optimization often produce code fragments unsuitable for sharing across processes or successive runs of the program, requiring a tradeoff be made between the efficiencies of precompiled and shared code and the advantages of adaptively specialized code. For example, several design provisions of CIL are present to allow for efficient shared libraries, possibly at the cost of more specialized JIT code. The JVM implementation on OS X uses a Java Shared Archive [3] to provide some of the benefits of shared libraries.

Comparison of application virtual machine implementations

In addition to the portable virtual machines described above, virtual machines are often used as an execution model for individual scripting languages, usually by an interpreter. This table lists specific virtual machine implementations, both of the above portable virtual machines, and of scripting language virtual machines.

Virtual machine Languages Comments Interpreter JIT Implementation language SLoC
Common Language Runtime (CLR) C#, C++/CLI, F#, VB.NET bytecode is CIL; .NET Core Runtime on GitHubNoYesC#, C++
Adobe Flash Player (aka Tamarin) ActionScript, SWF (file format)interactive web authoring tool. bytecode is named "ActionScript Byte Code (.abc)"YesYesC++135k (initially released)
Dis (Inferno) Limbo Dis Virtual Machine SpecificationYesYesC15k + 2850 per JIT arch + 500 per host OS
DotGNU-Portable.NET CLI languages including: C# Common Language Runtime cloneNoYesC, C#
Forth Forth Features are simplified, usually include assembler, compiler, text-level and binary-level interpreters, sometimes editor, debugger and OS. Compiling speeds are >20 SKLOC/S and behave much like JIT.YesNoForth, Forth Assembler2.8K to 5.6K; advanced, professional implementations are smaller.
Glulx Inform 6, Inform 7, othersYesNoVarious implementations exist
HHVM PHP, Hack Is an open-source virtual machine designed for executing programs written in Hack and PHP.YesYesC++, OCaml
Icon IconBase source code provides both the interpreter as well as an unsupported compile-to-C version. The runtime code, that is shared between the compiler and the interpreter, is written in a variant of C called RTT.YesNoC, RTT (a custom front-end to C, provided with the base source for Icon).~180k total. (source to bytecode: ~11k, bytecode interpreter: ~46k, iconc: ~23k, common/headers: ~13k, rtt: ~15k)
JVM Java, Kotlin, Jython, Groovy, JRuby, C, C++, Clojure, Scala and several othersReference implementation by Sun ; OpenJDK: code under GPL  ; IcedTea: code and tools under GPL YesYes JDK, OpenJDK & IcedTea with regular JIT : Java, C, C++, ASM ; IcedTea with the "Zero" JIT : Java, C, C++JVM is around 6500k lines; TCK is 80k tests and around 1000k lines
LLVM C, C++, Kotlin, Objective-C, Swift, Ada, Fortran, and Rust MSIL, C and C++ output are supported. ActionScript Byte Code output is supported by Adobe Alchemy. bytecode is named "LLVM Bytecode (.bc)". assembly is named "LLVM Assembly Language (*.ll)".YesYesC++811k [4]
Lua LuaYesLuaJITC13k + 7k LuaJIT
MMIX MMIXAL
Mono CLI languages including: C#, VB.NET, IronPython, IronRuby, and othersCommon Language Runtime cloneYesYesC#, C2332k
NekoVM currently Neko and Haxe Yesx86 onlyC46k
Oz Oz, Alice
O-code machine BCPL
p-code machine Pascal UCSD Pascal, widespread in late 70s including Apple IIYesNoassembly, Pascal
Parrot Perl 5, Raku, NQP-rx, PIR, PASM, PBC, BASIC, bc, C99, ECMAScript, Lisp, Lua, m4, Tcl, WMLScript, XML, and othersYesYesC, Perl111k C, 240k Perl
Perl virtual machine Perl op-code tree walkerYesNoC, Perl175k C, 9k Perl
CPython Python YesC387k C, 368k Python, 10k ASM, 31k Psyco
PyPy Python Self-hosting implementation of Python, next generation of Psyco YesYesPython
Rubinius Ruby Virtual machine for another Ruby implementationYesYesC++, Ruby
Silverlight C#, VB.NET A Micro-version of Microsoft .NET Framework to let applications run sandboxed inside browserYesYesC++7MB (initially released)
ScummVM Scumm Computer game engine
SECD ISWIM, Lispkit Lisp
Squirrel SquirrelYesSquirrel_JITC++12k
Smalltalk Smalltalk
SQLite SQLite opcodesVirtual database engine
Squeak Squeak Smalltalk Self hosting implementation of Squeak virtual machine. Rich multi-media support.YesCog & ExuperySmalltalk/Slang110k Smalltalk, ~300K C
SWI-Prolog Prolog: SWI-Prolog, YAP YesNoC, SWI-Prolog
TraceMonkey JavaScriptBased on Tamarin NoYesC++173k
TrueType TrueType Font rendering engineYesNoC (typically)
Valgrind x86/x86-64 binariesChecking of memory accesses and leaks under Linux C467k [5]
VisualWorks Smalltalk NoYesC
Vx32 virtual machine x86 binariesApplication-level virtualization for native codeNoYes
Waba Virtual machine for small devices, similar to Java
Yet Another Ruby VM (YARV) Ruby Virtual machine of the reference implementation for Ruby 1.9 and newer versionsYesYesC
Z-machine Z-Code
Zend Engine PHP YesNoC75k

See also

Related Research Articles

In computing, a compiler is a computer program that translates computer code written in one programming language into another language. The name "compiler" is primarily used for programs that translate source code from a high-level programming language to a low-level programming language to create an executable program.

<span class="mw-page-title-main">Java (programming language)</span> Object-oriented programming language

Java is a high-level, class-based, object-oriented programming language that is designed to have as few implementation dependencies as possible. It is a general-purpose programming language intended to let programmers write once, run anywhere (WORA), meaning that compiled Java code can run on all platforms that support Java without the need to recompile. Java applications are typically compiled to bytecode that can run on any Java virtual machine (JVM) regardless of the underlying computer architecture. The syntax of Java is similar to C and C++, but has fewer low-level facilities than either of them. The Java runtime provides dynamic capabilities that are typically not available in traditional compiled languages.

<span class="mw-page-title-main">Java virtual machine</span> Virtual machine that runs Java programs

A Java virtual machine (JVM) is a virtual machine that enables a computer to run Java programs as well as programs written in other languages that are also compiled to Java bytecode. The JVM is detailed by a specification that formally describes what is required in a JVM implementation. Having a specification ensures interoperability of Java programs across different implementations so that program authors using the Java Development Kit (JDK) need not worry about idiosyncrasies of the underlying hardware platform.

In computer programming, a p-code machine is a virtual machine designed to execute p-code. This term is applied both generically to all such machines, and to specific implementations, the most famous being the p-Machine of the Pascal-P system, particularly the UCSD Pascal implementation, among whose developers, the p in p-code was construed to mean pseudo more often than portable, thus pseudo-code meaning instructions for a pseudo-machine.

Java and C++ are two prominent object-oriented programming languages. By many language popularity metrics, the two languages have dominated object-oriented and high-performance software development for much of the 21st century, and are often directly compared and contrasted. Java's syntax was based on C/C++.

<span class="mw-page-title-main">Interpreter (computing)</span> Program that executes source code without a separate compilation step

In computer science, an interpreter is a computer program that directly executes instructions written in a programming or scripting language, without requiring them previously to have been compiled into a machine language program. An interpreter generally uses one of the following strategies for program execution:

  1. Parse the source code and perform its behavior directly;
  2. Translate source code into some efficient intermediate representation or object code and immediately execute that;
  3. Explicitly execute stored precompiled bytecode made by a compiler and matched with the interpreter Virtual Machine.

Bytecode is a form of instruction set designed for efficient execution by a software interpreter. Unlike human-readable source code, bytecodes are compact numeric codes, constants, and references that encode the result of compiler parsing and performing semantic analysis of things like type, scope, and nesting depths of program objects.

In computing, just-in-time (JIT) compilation is compilation during execution of a program rather than before execution. This may consist of source code translation but is more commonly bytecode translation to machine code, which is then executed directly. A system implementing a JIT compiler typically continuously analyses the code being executed and identifies parts of the code where the speedup gained from compilation or recompilation would outweigh the overhead of compiling that code.

In software design, the Java Native Interface (JNI) is a foreign function interface programming framework that enables Java code running in a Java virtual machine (JVM) to call and be called by native applications and libraries written in other languages such as C, C++ and assembly.

Rhino is a JavaScript engine written fully in Java and managed by the Mozilla Foundation as open source software. It is separate from the SpiderMonkey engine, which is also developed by Mozilla, but written in C++ and used in Mozilla Firefox.

Jazelle DBX is an extension that allows some ARM processors to execute Java bytecode in hardware as a third execution state alongside the existing ARM and Thumb modes. Jazelle functionality was specified in the ARMv5TEJ architecture and the first processor with Jazelle technology was the ARM926EJ-S. Jazelle is denoted by a "J" appended to the CPU name, except for post-v5 cores where it is required for architecture conformance.

<span class="mw-page-title-main">Java (software platform)</span> Set of computer software and specifications

Java is a set of computer software and specifications that provides a software platform for developing application software and deploying it in a cross-platform computing environment. Java is used in a wide variety of computing platforms from embedded devices and mobile phones to enterprise servers and supercomputers. Java applets, which are less common than standalone Java applications, were commonly run in secure, sandboxed environments to provide many features of native applications through being embedded in HTML pages.

In computer programming, a programming language implementation is a system for executing computer programs. There are two general approaches to programming language implementation:

In software development, the programming language Java was historically considered slower than the fastest 3rd generation typed languages such as C and C++. In contrast to those languages, Java compiles by default to a Java Virtual Machine (JVM) with operations distinct from those of the actual computer hardware. Early JVM implementations were interpreters; they simulated the virtual operations one-by-one rather than translating them into machine code for direct hardware execution.

Eclipse OpenJ9 is a high performance, scalable, Java virtual machine (JVM) implementation that is fully compliant with the Java Virtual Machine Specification.

<span class="mw-page-title-main">Da Vinci Machine</span> Sun Microsystems project

The Da Vinci Machine, also called the Multi Language Virtual Machine, was a Sun Microsystems project aiming to prototype the extension of the Java Virtual Machine (JVM) to add support for dynamic languages.

Java bytecode is the instruction set of the Java virtual machine (JVM), crucial for executing programs written in the Java language and other JVM-compatible languages. Each bytecode operation in the JVM is represented by a single byte, hence the name "bytecode", making it a compact form of instruction. This intermediate form enables Java programs to be platform-independent, as they are compiled not to native machine code but to a universally executable format across different JVM implementations.

<span class="mw-page-title-main">GraalVM</span> Virtual machine software

GraalVM is a Java Development Kit (JDK), written in Java. The open-source distribution of GraalVM is based on OpenJDK, and the enterprise distribution is based on Oracle JDK. As well as just-in-time (JIT) compilation, GraalVM can compile a Java application ahead-of-time so that it starts instantly, provides peak performance with no warmup, and uses fewer resources. It provides additional programming languages and execution modes. The first production-ready release, GraalVM 19.0, was distributed in May 2019. The most recent release is GraalVM for JDK 21, made available in September 2023.

References

  1. "The Java Community Process(SM) Program - JSRs: Java Specification Requests - detail JSR# 292". Jcp.org. Retrieved 2013-07-04.
  2. "JITRewrite – Parrot". Trac.parrot.org. Retrieved 2013-07-04.
  3. Apple docs on OS X use of Java Shared Archive
  4. The LLVM Compiler Infrastructure Archived 2012-07-31 at the Wayback Machine , ohloh.net, 2011 Nov 30
  5. Valgrind, ohloh.net, 2011 Nov 30.