O Que É uma Máquina Virtual em Linguagens de Programação?
Uma máquina virtual de linguagem é um runtime de software que executa um programa escrito em bytecode, escondendo os detalhes da CPU e do sistema operacional reais por baixo.
Este é um tipo de máquina virtual diferente daquelas que rodam sistemas operacionais inteiros. Uma VM de linguagem, como a Java Virtual Machine ou o .NET Common Language Runtime, é um programa que carrega bytecode e o roda. Ela fornece gerenciamento de memória, threading e um modelo de execução consistente, para que o mesmo programa compilado se comporte igual em todo lugar onde a VM está instalada.
O que uma VM de linguagem fornece
Uma VM de linguagem dá aos programas uma máquina abstrata a que mirar: um conjunto de instruções definido (bytecode), gerenciamento automático de memória e uma biblioteca padrão. Seu código conversa com a VM, e a VM conversa com o hardware real em seu nome.
Não é o mesmo que uma VM de sistema
Uma máquina virtual de sistema (como uma criada com VMware ou na cloud) emula um computador inteiro e roda um sistema operacional convidado. Uma VM de linguagem só roda programas em um formato de bytecode. Elas compartilham o nome, mas resolvem problemas diferentes.
O que as VMs cuidam por você
- Alocação de memória e garbage collection.
- Compilação just-in-time do bytecode quente para código nativo.
- Escalonamento de threads e primitivas de sincronização.
- Uma abstração portátil sobre diferentes CPUs e sistemas operacionais.
Por que as VMs vencem em portabilidade
Como a VM absorve as diferenças de plataforma, um artifact compilado roda sem alteração em Linux, macOS e Windows. Você entrega bytecode, e qualquer VM presente o executa corretamente.
Um exemplo rápido
Rodar java -jar app.jar inicia a JVM, que carrega seu bytecode, faz JIT das partes movimentadas, gerencia memória e roda o programa. Você nunca escreve instruções de CPU por conta própria; a VM faz.
VMs de linguagem no CI
Linguagens baseadas em VM podem ser famintas por memória, e o tamanho do heap da VM importa. Uma suíte de testes que excede o heap configurado lançará erros de out-of-memory e pode ser encerrada pelo runner. Runners maiores (Latchkey) dão mais folga à VM, e kills transitórios por OOM podem ser reexecutados automaticamente para que picos de recurso flaky não bloqueiem merges.
Principais conclusões
- Uma VM de linguagem roda bytecode e abstrai a CPU e o SO subjacentes.
- Ela é distinta de uma VM de sistema que emula um computador inteiro.
- A VM cuida de memória, threads e compilação JIT por você.