Desmistificando o JVM, JRE e JDK
JVM, JRE e JDK: afinal, qual é a diferença?
Seção intitulada “JVM, JRE e JDK: afinal, qual é a diferença?”Se você está começando a estudar Java, provavelmente já encontrou três siglas que aparecem o tempo todo:
JVM, JRE e JDK.
À primeira vista, elas parecem representar praticamente a mesma coisa. E, para piorar, muitos materiais explicam esses conceitos usando definições bastante técnicas antes mesmo de explicar como eles se relacionam.
Uma forma simples de entender isso é imaginar que estamos falando de uma cozinha.
🍳 Imagine que Java é uma cozinha
Seção intitulada “🍳 Imagine que Java é uma cozinha”Vamos começar pelo conceito mais importante.
Quando escrevemos um programa Java, o código que criamos não é executado diretamente pelo sistema operacional.
Por exemplo, podemos escrever:
public class Main { public static void main(String[] args) { System.out.println("Hello, World!"); }}Esse código é transformado pelo compilador em bytecode, normalmente armazenado em um arquivo .class.
É aí que entram JVM, JRE e JDK.
JVM — o cozinheiro
Seção intitulada “JVM — o cozinheiro”A JVM (Java Virtual Machine) pode ser comparada ao cozinheiro da nossa cozinha.
É ela quem pega o bytecode Java e efetivamente executa o programa.
Quando você executa:
java Maina JVM entra em ação.
Ela interpreta ou compila o bytecode para instruções que o computador consegue executar, utilizando técnicas como JIT (Just-In-Time compilation) durante a execução.
E aqui está uma das grandes ideias por trás do Java:
O mesmo bytecode pode ser executado em diferentes sistemas operacionais, desde que exista uma JVM adequada para aquele sistema.
Por isso, podemos ter:
Main.class │ ┌────────┼────────┐ ↓ ↓ ↓ JVM JVM JVM Windows Linux macOS │ │ │ ↓ ↓ ↓ CPU CPU CPUO bytecode continua sendo o mesmo.
O que muda é a implementação da JVM responsável por conversar com o sistema operacional e o hardware.
É daí que vem a famosa ideia:
“Write once, run anywhere.”
Escreva uma vez, execute em qualquer lugar.
JRE — a cozinha
Seção intitulada “JRE — a cozinha”Agora imagine que o cozinheiro sozinho não consegue fazer muita coisa.
Ele precisa de uma cozinha, utensílios, ingredientes e toda a estrutura necessária para preparar o prato.
Essa é uma boa forma de imaginar o JRE (Java Runtime Environment).
Conceitualmente, o JRE representa o ambiente necessário para executar aplicações Java.
Podemos simplificar assim:
JRE├── JVM└── Bibliotecas necessárias para execuçãoOu, usando nossa analogia:
JRE = Cozinha + Cozinheiro + Recursos necessáriosSe você simplesmente quer executar uma aplicação Java, você não precisa necessariamente de todas as ferramentas utilizadas pelo desenvolvedor para construir aquela aplicação.
É a diferença entre:
“Quero preparar esta receita.”
e:
“Quero criar novas receitas.”
No primeiro caso, precisamos da estrutura necessária para cozinhar.
No segundo, precisamos de ferramentas adicionais.
JDK — a cozinha completa para o desenvolvedor
Seção intitulada “JDK — a cozinha completa para o desenvolvedor”É aí que entra o JDK (Java Development Kit).
Se o JRE representa o ambiente necessário para executar aplicações Java, o JDK representa o conjunto de ferramentas necessário para desenvolver essas aplicações.
Podemos imaginar:
JDK├── JRE│ └── JVM└── Ferramentas de desenvolvimentoEntre essas ferramentas está o famoso:
javacO javac é o compilador Java.
Quando fazemos:
javac Main.javao compilador transforma nosso código-fonte:
Main.javaem bytecode:
Main.classDepois, podemos executar esse bytecode utilizando a JVM:
java MainPortanto, o fluxo simplificado seria:
Desenvolvedor │ ↓ Main.java │ │ javac ↓ Main.class │ │ JVM ↓ Programa rodandoEntão qual é a diferença?
Seção intitulada “Então qual é a diferença?”Podemos resumir tudo em uma frase:
JDK desenvolve, JRE fornece o ambiente de execução e JVM executa o bytecode.
Ou, usando nossa analogia:
| Conceito | Analogia | Responsabilidade |
|---|---|---|
| JVM | 👨🍳 Cozinheiro | Executa o bytecode |
| JRE | 🍳 Cozinha | Fornece o ambiente necessário para executar Java |
| JDK | 🧰 Cozinha completa | Fornece ferramentas para desenvolver aplicações Java |
A relação pode ser visualizada desta maneira:
┌─────────────────────────────────┐│ JDK ││ ││ ┌─────────────────────────┐ ││ │ JRE │ ││ │ │ ││ │ ┌───────────┐ │ ││ │ │ JVM │ │ ││ │ └───────────┘ │ ││ │ │ ││ └─────────────────────────┘ ││ ││ + ferramentas de desenvolvimento│└─────────────────────────────────┘Mas existe um detalhe importante
Seção intitulada “Mas existe um detalhe importante”Essa representação é muito útil para entender os conceitos, mas existe uma ressalva importante.
Atualmente, especialmente a partir do Java 11, a ideia de instalar um “JRE separado” não funciona mais da mesma forma que funcionava em versões antigas do Java.
Distribuições modernas do OpenJDK normalmente são distribuídas como JDKs, e ferramentas como jlink podem ser utilizadas para criar runtimes personalizados.
Por isso, hoje é comum um desenvolvedor simplesmente instalar um JDK, como:
OpenJDKTemurinOracle JDKAmazon Correttoe utilizar esse ambiente tanto para desenvolver quanto para executar suas aplicações.
Isso não torna o conceito de JRE inútil.
Pelo contrário.
A distinção continua sendo bastante útil para entender o que uma aplicação Java precisa para ser executada e quais componentes fazem parte do ecossistema Java.
E onde entra o Java?
Seção intitulada “E onde entra o Java?”Aqui existe outra confusão bastante comum.
Quando falamos “Java”, podemos estar falando de coisas diferentes:
Java├── Linguagem Java├── Plataforma Java├── JVM├── Bibliotecas└── Ferramentas do JDKA linguagem é aquilo que escrevemos:
System.out.println("Hello World");O compilador transforma esse código em bytecode.
A JVM executa esse bytecode.
E o JDK fornece as ferramentas necessárias para construir todo esse processo.
Uma analogia completa
Seção intitulada “Uma analogia completa”Voltando para nossa cozinha, podemos pensar em todo o processo assim:
Você é o desenvolvedor.
Você escreve uma receita:
Main.javaO JDK fornece as ferramentas necessárias para transformar essa receita em algo que possa ser executado.
O JRE representa a estrutura necessária para executar aquilo.
E a JVM é quem efetivamente prepara a receita.
No final:
Você │ │ escreve ↓Java (.java) │ │ JDK / javac ↓Bytecode (.class) │ │ JVM ↓Aplicação executandoEssa separação é uma das características que tornam o ecossistema Java tão interessante.
O programa não precisa ser compilado diretamente para cada sistema operacional.
Ele é compilado para bytecode, e a JVM de cada plataforma fica responsável por executar esse bytecode.
Para guardar
Seção intitulada “Para guardar”Se você está começando no Java, não precisa decorar dezenas de definições.
Lembre apenas:
JDK → ferramentas para desenvolver
JRE → ambiente para executar
JVM → máquina virtual que executa o bytecode
Ou, na nossa cozinha:
👨💻 JDK é o kit do desenvolvedor.
🍳 JRE é o ambiente de execução.
👨🍳 JVM é quem executa o programa.
Entendendo essa relação, fica muito mais fácil compreender o restante do ecossistema Java.