1. Contenidos
1.1 Distintas formas de ejecutar un programa
No todos los lenguajes llegan a la CPU siguiendo el mismo proceso. Podemos encontrar, de forma simplificada, tres estrategias:
- compilación nativa: el programa se transforma previamente en código específico de una plataforma;
- interpretación: otro programa procesa y ejecuta las instrucciones durante la ejecución;
- código intermedio: el código fuente se transforma en una representación intermedia que después ejecuta una máquina virtual.
1.2 Código intermedio
El código intermedio es una representación situada entre el código fuente y el código máquina específico de una arquitectura.
Código fuente
↓
Compilador
↓
Código intermedio
↓
Entorno de ejecución / máquina virtual
↓
Código máquina
↓
CPU
La principal idea es que el código intermedio no se genera directamente para una CPU concreta.
1.3 Java y bytecode
Java es un ejemplo muy conocido. El desarrollador escribe:
public class Emporio {
public static void main(String[] args) {
System.out.println("El Emporio Arcano");
}
}
El archivo fuente Emporio.java se compila con:
javac Emporio.java
y se obtiene:
Emporio.class
Un archivo .class contiene bytecode Java, un tipo de código intermedio.
1.4 La JVM
La JVM (Java Virtual Machine) es la máquina virtual que ejecuta bytecode Java.
Emporio.class
↓
JVM
↓
Sistema operativo
↓
CPU
Para ejecutar el programa usamos normalmente:
java Emporio
1.5 Portabilidad
Una ventaja importante del código intermedio es la portabilidad. El mismo bytecode puede ejecutarse en distintas plataformas si existe una JVM compatible para cada una.
Emporio.class
│
┌──────────────┼──────────────┐
↓ ↓ ↓
JVM Windows JVM Linux JVM macOS
↓ ↓ ↓
Windows Linux macOS
Esto reduce la dependencia entre el programa compilado y una máquina física concreta.
1.6 Interpretación y compilación JIT
Una máquina virtual puede ejecutar el código intermedio mediante diferentes técnicas. Una de ellas es la compilación JIT (Just In Time), que transforma durante la ejecución determinadas partes del bytecode en código máquina nativo.
Bytecode → JVM → interpretación / JIT → código máquina → CPU
Esto permite combinar portabilidad y buen rendimiento.
1.7 Máquina virtual de lenguaje y máquina virtual de sistema
No debemos confundir una máquina virtual como la JVM con productos que virtualizan un equipo completo.
- JVM: entorno diseñado para ejecutar bytecode Java.
- VirtualBox, VMware, Hyper-V: permiten ejecutar sistemas operativos completos sobre hardware virtualizado.
1.8 Comparación de modelos
| Modelo | Proceso simplificado | Ejemplo |
| Compilación nativa | Fuente → ejecutable nativo | C |
| Interpretación | Fuente → intérprete → ejecución | Python, de forma simplificada |
| Código intermedio | Fuente → bytecode → máquina virtual | Java |
Los lenguajes modernos pueden combinar varias técnicas. La clasificación anterior es útil para comprender los modelos principales, no para describir todos los detalles internos de cada implementación.