El software de virtualización de aplicaciones se refiere tanto a las máquinas virtuales de aplicaciones como al software responsable de su implementación. Las máquinas virtuales de aplicaciones se utilizan normalmente para permitir que el código de bytes de una aplicación se ejecute de forma portable en diversas arquitecturas informáticas y sistemas operativos. La aplicación suele ejecutarse en el ordenador mediante un intérprete o compilación justo a tiempo (JIT). A menudo existen varias implementaciones de una misma máquina virtual, cada una con un conjunto diferente de funciones.
Comparación de máquinas virtuales
La tabla que se muestra aquí resume los elementos para los que se pretende que los diseños de máquinas virtuales sean eficientes, no la lista de capacidades presentes en ninguna implementación.
Las instrucciones de las máquinas virtuales procesan datos en variables locales utilizando un modelo principal de computación , generalmente el de una máquina de pila , una máquina de registros o una máquina de acceso aleatorio , a menudo denominada máquina de memoria. El uso de estos tres métodos se justifica por las diferentes ventajas y desventajas de las máquinas virtuales frente a las físicas, como la facilidad de interpretación, compilación y verificación de seguridad.
La gestión de memoria en estas máquinas virtuales portátiles se aborda a un nivel de abstracción superior al de las máquinas físicas. Algunas máquinas virtuales, como las populares máquinas virtuales Java (JVM), manejan direcciones de memoria de tal manera que requieren una gestión de memoria automática y segura, permitiendo que la máquina virtual rastree las referencias a punteros e impidiendo que las instrucciones de la máquina construyan punteros a memoria manualmente. Otras máquinas virtuales, como LLVM, se asemejan más a las máquinas físicas tradicionales, permitiendo el uso y la manipulación directa de punteros. El Lenguaje Intermedio Común (CIL) ofrece una solución híbrida, permitiendo tanto el uso controlado de la memoria (como la JVM, que permite una gestión de memoria automática y segura) como un modo "inseguro" que permite la manipulación directa de punteros de maneras que pueden violar los límites de tipo y los permisos.
La seguridad del código generalmente se refiere a la capacidad de la máquina virtual portátil para ejecutar código, otorgándole únicamente un conjunto predefinido de funcionalidades. Por ejemplo, la máquina virtual podría permitir que el código acceda solo a un conjunto específico de funciones o datos. Los mismos controles sobre punteros que posibilitan la gestión automática de la memoria y permiten que la máquina virtual garantice un acceso seguro a los datos se utilizan para asegurar que un fragmento de código solo tenga acceso a ciertos elementos de la memoria y no pueda eludir la propia máquina virtual. Posteriormente, se añaden otros mecanismos de seguridad, como verificadores de código, verificadores de pila y otros métodos.
Un intérprete permite cargar y ejecutar inmediatamente programas compuestos por instrucciones virtuales sin necesidad de una compilación, potencialmente costosa, a instrucciones de máquina nativas. Cualquier máquina virtual ejecutable puede interpretarse, por lo que la designación de la columna indica si el diseño incluye disposiciones para una interpretación eficiente (para uso común).
La compilación justo a tiempo (JIT) se refiere a un método para compilar instrucciones nativas en el último momento posible, generalmente justo antes o durante la ejecución del programa. El desafío de JIT radica más en su implementación que en el diseño de la máquina virtual; sin embargo, los diseños modernos han comenzado a considerar aspectos que mejoran la eficiencia. Los métodos JIT más sencillos compilan el código en un fragmento similar al de un compilador fuera de línea. No obstante, a menudo se emplean métodos más complejos que especializan los fragmentos de código compilados en parámetros conocidos solo en tiempo de ejecución (véase Optimización adaptativa ).
La compilación anticipada (AOT) se refiere al método clásico de usar un precompilador para generar un conjunto de instrucciones nativas que no cambian durante la ejecución del programa. Dado que la compilación y optimización intensivas pueden llevar tiempo, un programa precompilado puede iniciarse más rápido que uno que se basa únicamente en JIT para su ejecución. Las implementaciones de la JVM han mitigado este costo inicial mediante la interpretación inicial para acelerar los tiempos de inicio, hasta que JIT pueda generar los fragmentos de código nativo.
Las bibliotecas compartidas son una herramienta para reutilizar segmentos de código nativo en múltiples programas en ejecución. En los sistemas operativos modernos, esto generalmente implica usar memoria virtual para compartir las páginas de memoria que contienen una biblioteca compartida entre diferentes procesos, los cuales están protegidos entre sí mediante protección de memoria . Es interesante observar que los métodos JIT agresivos, como la optimización adaptativa, a menudo producen fragmentos de código inadecuados para ser compartidos entre procesos o ejecuciones sucesivas del programa, lo que requiere un equilibrio entre la eficiencia del código precompilado y compartido y las ventajas del código especializado adaptativo. Por ejemplo, varias disposiciones de diseño de CIL están presentes para permitir bibliotecas compartidas eficientes, posiblemente a costa de un código JIT más especializado. La implementación de la JVM en OS X utiliza un Java Shared Archive [ 4 ] para proporcionar algunos de los beneficios de las bibliotecas compartidas.
Comparación de implementaciones de máquinas virtuales de aplicaciones
Además de las máquinas virtuales portátiles descritas anteriormente, las máquinas virtuales se utilizan con frecuencia como modelo de ejecución para lenguajes de scripting específicos, generalmente mediante un intérprete. Esta tabla enumera implementaciones específicas de máquinas virtuales, tanto de las máquinas virtuales portátiles mencionadas como de las máquinas virtuales para lenguajes de scripting.
Véase también
- Virtualización de aplicaciones
- Encuadernación lingüística
- Interfaz de funciones externas
- Convención de llamadas
- Deformación de nombres
- Interfaz de programación de aplicaciones (API)
- Interfaz binaria de la aplicación (ABI)
- Comparación de software de virtualización de plataformas
- Comparación de máquinas virtuales Java
- Lista de máquinas virtuales Java
- Lista de motores ECMAScript
- Lista de servidores de aplicaciones
- WebAssembly
Referencias
- ↑ "El programa Java Community Process(SM) - JSRs: Java Specification Requests - detalle JSR# 292" . Jcp.org . Consultado el 4 de julio de 2013 .
- ↑ "JITRewrite – Parrot" . Trac.parrot.org . Consultado el 4 de julio de 2013 .
- ↑ "Implementación de StoffelVM" . Documentación de Stoffel . Consultado el 30 de enero de 2026 .
- ↑ Documentación de Apple sobre el uso de Java Shared Archive en OS X
- ↑ "Un vistazo más de cerca al intérprete - Erlang/OTP" .
- ↑ "Un primer vistazo al JIT - Erlang/OTP" .
- ↑ La infraestructura del compilador LLVM archivada el 31/07/2012 en Wayback Machine , ohloh.net, 30 de noviembre de 2011
- ↑ "Implementación de StoffelVM" . Documentación de Stoffel . Consultado el 30 de enero de 2026 .
- ^ "Descripción general de StoffelLang" . Documentación Stoffel . Consultado el 30 de enero de 2026 .
- ↑ Valgrind , ohloh.net, 30 de noviembre de 2011.
- Comparación de software
- Software de virtualización