O que e o Project Valhalla

O Project Valhalla e uma iniciativa da OpenJDK para trazer value types e primitivos genéricos a plataforma Java. O projeto foi anunciado oficialmente em 2014 por Brian Goetz, arquiteto da linguagem Java na Oracle. Depois de mais de uma década de pesquisa e iteracoes, as primeiras features chegam como preview no JDK 23 e se consolidam no JDK 28.

O problema central que o Valhalla resolve e antigo: em Java, tudo que não e primitivo (int, long, double...) vive no heap e requer alocacao e coleta de lixo. Isso cria pressão no garbage collector e degrada a performance em aplicações que manipulam muitos objetos pequenos, como sistemas financeiros, jogos e processamento científico.

Com value types, você pode criar classes que se comportam como primitivos: sem identidade, sem referência, armazenadas inline na stack ou em arrays contínuos na memoria. O slogan do projeto resume bem: "codes like a class, works like an int".

Como funciona

O mecanismo central do Valhalla são as value classes. Ao declarar uma classe com a palavra-chave value, você instruí a JVM a tratar instâncias dessa classe como valores imutáveis sem identidade de objeto. Isso muda radicalmente como a JVM aloca e acessa esses dados.

Sem value types, um array de objetos Point em Java armazena referências (ponteiros) para objetos espalhados no heap. Com value types, o array armazena os dados diretamente em memoria continua, igual a como C e C++ fazem. Isso melhora drasticamente a localidade de cache da CPU, que e um dos maiores gargalos de performance na JVM.

A JVM também ganha a capacidade de escalarizacao: decompor um objeto em seus campos primitivos durante a compilação JIT, eliminando alocacoes por completo em muitos casos. Para aplicações que criam milhões de objetos pequenos por segundo, o ganho pode ser enorme.

Principais recursos do Project Valhalla

O JDK 28 traz as seguintes features do Valhalla como parte do pacote:

  • Value classes: declara classes imutáveis sem identidade. Instâncias não podem ser usadas com == para identidade nem com synchronized.
  • Primitive classes: subconjunto de value classes com suporte a operações primitivas e representação inline garantida.
  • Generics com primitivos: finalmente e possível usar List<int> sem boxing para Integer. Isso elimina um dos maiores desperdícios de memoria do Java moderno.
  • Null-restricted types: tipos que não podem ser nulos, eliminando NullPointerException em campos tipados.
  • Layout de memoria otimizado: arrays e colecoes de value classes ficam contínuos na memoria, como arrays de primitivos.

A retrocompatibilidade e uma prioridade: código Java existente continua compilando e rodando sem alterações. As novas features são opt-in.

Como começar com o Project Valhalla no JDK 28

Para experimentar o Valhalla, você precisa do JDK 28 ou superior. Use o SDKMAN para instalar sem afetar seu ambiente atual:

sdk install java 28-open
sdk use java 28-open
java -version

Crie uma value class simples para testar. Declare a classe com a palavra-chave value e torne todos os campos finais:

value class Point {
    double x;
    double y;

    Point(double x, double y) {
        this.x = x;
        this.y = y;
    }
}

Para compilar com as features em preview (se necessário no JDK 28), use as flags:

javac --enable-preview --release 28 Main.java
java --enable-preview Main

Exemplo prático: ponto 2D sem boxing

O caso clássico para value types e geometria computacional ou física de jogos. Imagine processar um array de 10 milhões de pontos 2D. Com o Java atual, cada objeto Point e uma referência no heap: 10 milhões de alocacoes, 10 milhões de objetos para o GC rastrear.

Com value types no JDK 28, o array de Point fica continuo na memoria, como um double[]. O garbage collector não precisa rastrear 10 milhões de objetos individuais. Em benchmarks divulgados pela equipe do OpenJDK, operações sobre arrays de value types são até 3 a 5 vezes mais rápidas que as equivalentes com objetos normais em cenários de alta alocacao.

O beneficio real aparece em sistemas que rodam 24 horas e sofrem com pauses do GC. Com value types, você reduz a pressão no heap e as pausas ficam menores e menos frequentes, o que impacta diretamente na latência de sistemas em produção.

Comparacao com alternativas

Antes do Valhalla, desenvolvedores Java usavam workarounds para conseguir performance parecida com value types:

  • Campos primitivos separados: substituir Point por arrays paralelos (double[] xs, double[] ys). Funciona, mas destrói a legibilidade do código.
  • Records (JDK 16+): records são imutáveis mas ainda são objetos no heap. O Valhalla complementa records, não substitui.
  • Off-heap com MemorySegment (Panamá): o Project Panamá permite gerenciar memoria fora do heap manualmente. Poderoso, mas complexo e sem garbage collection.
  • Kotlin value classes: Kotlin tem @JvmInline value class mas com limitacoes de um único campo. O Valhalla e mais completo e nativo na JVM.

Linguagens como C#, com struct, e Rust, com tipos na stack por padrão, sempre tiveram essa vantagem. O Valhalla traz o Java para paridade sem abandonar o modelo de orientacao a objetos.

Pontos positivos e limitacoes

Os pontos positivos são concretos: performance significativamente melhor para workloads de alta alocacao, generics com primitivos que eliminam o boxing existente desde o Java 5, retrocompatibilidade total com código legado, e integração natural com records e sealed classes do Java moderno.

As limitacoes reais que você vai encontrar: value classes não podem ser nulas por padrão, o que muda o modelo mental de alguns padrões de design. Sem sincronizacao em value classes - não da para usar synchronized nelas. Features chegam como preview no JDK 28, então detalhes da API podem mudar. Frameworks como Hibernate e Spring precisarão de adaptacoes para aproveitar ao máximo.

O maior risco e o uso indiscriminado: value types não são melhores que objetos em todos os casos. Para objetos com identidade, mutáveis ou que precisam de sincronizacao, o modelo atual continua sendo o correto. A regra prática: se você precisaria de equals() baseado em campos ao invés de identidade, e um candidato a value class.

Casos de uso reais para value types

Sistemas financeiros: tipos como Money, Price e Percentage são perfeitos para value classes. São imutáveis por natureza, sem identidade necessária, e criados e descartados aos milhões por segundo em sistemas de trading de alta frequência.

Jogos e simulações: vetores 2D/3D, quaternions, cores RGBA e posições são os casos clássicos. A física de um jogo pode criar e descartar centenas de milhares de vetores por frame. Com value types, isso vira processamento em arrays contínuos, muito mais amigável para o cache da CPU.

Processamento científico e machine learning: matrizes e tensores beneficiam diretamente. Bibliotecas de álgebra linear em Java poderão armazenar dados numéricos com zero boxing, aproximando a performance da JVM do C++ nessas operações.

APIs de data e hora: os tipos do java.time como LocalDate, Duration e Instant são candidatos naturais a value types em versões futuras da biblioteca padrão do Java.

Dicas e boas práticas com o Project Valhalla

Antes de converter uma classe existente para value, verifique se ela e realmente imutável e sem necessidade de identidade. Uma classe que usa == para comparacao ou que precisa de synchronized não pode ser uma value class sem refatoracao.

Use records como ponto de partida: se sua classe já e um record, a migração para value class e mais simples. A combinacao value record Point(double x, double y) deve funcionar em versões futuras do JDK, pois records já são imutáveis por definição.

Para medir o impacto real, use o JMH (Java Microbenchmark Harness) antes e depois da migração. O ganho varia muito: arrays de value types mostram ganhos expressivos, mas objetos únicos raramente apresentam diferença mensurável. Fique de olho nos JEPs oficiais: JEP 401 (value classes), JEP 402 (primitive classes) e JEP 218 (generics com primitivos) são os documentos que detalham o comportamento exato de cada feature.

Vale a pena estudar o Project Valhalla?

Se você trabalha com Java em sistemas de alta performance - serviços financeiros, jogos, processamento de dados em larga escala - sim, o Valhalla e obrigatório. A melhoria de performance pode ser a diferença entre precisar escalar horizontalmente ou não.

Para a maioria dos desenvolvedores Java corporativos, o impacto mais imediato vai ser indireto: via frameworks e bibliotecas que vao adotar value types internamente. Você vai se beneficiar sem precisar escrever uma única value class.

O próximo passo concreto: instale o JDK 28 via SDKMAN, crie um projeto de teste com JMH e compare um array de Point normal com um value Point. Ver os números na prática e a melhor forma de entender o impacto real para o seu caso de uso.