Máquina virtual Java
Entorno de ejecución
Para poder ejecutar una aplicación en una Máquina Virtual de Java, el programa código debe compilarse de acuerdo a un formato binario portable estandarizado, normalmente en forma de ficheros con extensión .class. Un programa puede componerse de múltiples clases, en cuyo caso cada clase tendrá asociado su propio archivo .class. Para facilitar la distribución de aplicaciones, los archivos de clase pueden empaquetarse juntos en un archivo con formato jar. Esta idea apareció en la época de los primeros applets de Java. Estas aplicaciones pueden descargar aquellos archivos de clase que necesitan en tiempo de ejecución, lo que suponía una sobrecarga considerable para la red en una época donde la velocidad suponía un problema. El empaquetado evita la sobrecarga por la continua apertura y cierre de conexiones para cada uno de los fragmentos necesarios.
El código resultante de la compilación es ejecutado por la JVM que lleva a cabo la emulación del conjunto de instrucciones, bien por un proceso de interpretación o más habitualmente mediante un compilador JIT (Just In Time), como el HotSpot de Sun. Esta última opción convierte el bytecode a código nativo de la plataforma destino, lo que permite una ejecución mucho más rápida. El inconveniente es el tiempo necesario al principio para la compilación.
En un sentido amplio, la Máquina Virtual de Java actúa como un puente entre el resultado de la compilación (el bytecode) y el sistema sobre el que se ejecuta la aplicación. Para cada dispositivo debe haber una JVM específica, ya sea un teléfono móvil, un PC con Windows XP o un microondas. En cualquier caso, cada máquina virtual conoce el conjunto de instrucciones de la plataforma destino, y traduce un código escrito en lenguaje Java (común para todas) al código nativo que es capaz de entender el hardware de la plataforma.
El verificador del bytecode
La JVM «verifica» todo bytecode antes de ejecutarlo. Esto significa que solo una cantidad limitada de secuencias de bytecode forman programas válidos; por ejemplo, una instrucción JUMP (branch) puede apuntar solo a una instrucción dentro de la misma función. A causa de esto, el hecho de que JVM es una arquitectura de pila no implica una carga en la velocidad para emulación sobre arquitecturas basadas en registros cuando usamos un compilador JIT: no hay diferencia para un compilador JIT si nombra registros con nombres imaginarios o posiciones de pila imaginarias que necesitan ser ubicadas a los registros de la arquitectura objetivo. De hecho, la verificación de código hace a la JVM diferente de una arquitectura clásica de pila cuya emulación eficiente con un compilador JIT es más complicada y típicamente realizado por un intérprete más lento.
La verificación de código también asegura que los patrones de bits arbitrarios no pueden usarse como direcciones. La protección de memoria se consigue sin necesidad de una unidad de Gestión de Memoria (MMU). Así, JVM es una forma eficiente de obtener protección de memoria en chips que no tienen MMU.
Bytecodes
La JVM tiene instrucciones para los siguientes grupos de tareas:
- Carga y almacenamiento
- Aritmética
- Conversión de tipos
- Creación y manipulación de objetos
- Gestión de pilas (push y pop)
- Transferencias de control (branching)
- Invocación y retorno a métodos
- Excepciones
La clave es la compatibilidad binaria. Cada sistema operativo de un host particular necesita su propia implementación de JVM y runtime. Estas JVM interpretan el bytecode semánticamente de la misma manera, pero la implementación actual puede variar. Más complicado que solo la emulación de bytecode es la implementación compatible y eficiente de las API Java, las cuales tienen que ser mapeadas para cada sistema operativo de host.
Extensión segura de código remoto
Una arquitectura de máquina virtual permite control de granularidad fina sobre las acciones que el código puede hacer dentro de la máquina. Esto está diseñado para permitir ejecución segura de código no confiable desde fuentes remotas; un modelo usado muy famoso son las Java applets. Applets se ejecutan dentro de una VM incorporada en el navegador del usuario, ejecutando código descargado desde un servidor HTTP remoto. El código remoto se ejecuta en una "sandbox" altamente restringida, la cual está diseñada para proteger al usuario de código erróneo o malicioso. Los publicadores con recursos financieros suficientes pueden conseguir un certificado con el cual hacer applets con firma digital que las caractericen como seguras ("safe"), dándoles entonces permisos para salir de la sandbox y acceder al sistema de ficheros local y sistema de red, presumiblemente bajo el control del usuario.
Implementaciones de la máquina virtual
La edición J2SE tiene dos implementaciones de la máquina virtual:
- Java HotSpot Client VM: La máquina virtual por defecto, preparada para obtener el máximo rendimiento en la ejecución de aplicaciones en el entorno cliente, por ejemplo, reduciendo al máximo el tiempo de inicio de una aplicación Java.
- Java HotSpot Server VM: Preparada para obtener el máximo rendimiento en la ejecución de aplicaciones en el entorno de los servidores.
Véase también
- Java
- Java Community Process
- Máquina de pila
- Lenguaje de programación orientado a pila
- Procesador Java
Referencias
Enlaces externos
- Kaffe.org - the Kaffe project
- Java Virtual Machine Descargar
- JamVM - The Jam Virtual Machine
- Una introducción a la estructura y funcionalidad básica de la Máquina Virtual Java
- Prueba tu JVM
- Sitio principal de Sun Microsystems (inglés)
- Descarga de Java SUN (enlace roto disponible en Internet Archive; véase el historial, la primera versión y la última). (en inglés)
- Clarificaciones y Enmiendas a la Especificación de la Máquina Virtual Java, Segunda Edición incluye lista de cambios que hay que realizar para soportar J2SE 5.0 y JSR 45
- JSR 45 – Especifica cambios al formato de fichero class para soportar depuración a nivel de fuente de lenguajes tales como JSP y SQLJ que son traducidos a Java