Java 25 LTS reduce la cabecera de cada objeto de 96 a 64 bits
@programacionLo esencial
- Java 25 es la nueva versión LTS (Long-Term Support), liberada el 16 de septiembre de 2025, sucesora de Java 21.
- JEP 519 introduce cabeceras de objeto compactas: bajan de 96/128 bits a 64 bits por instancia en la JVM.
- JEP 506 finaliza Scoped Values, alternativa inmutable a ThreadLocal para pasar datos entre hilos.
- JEP 511 finaliza Module Import Declarations: import module java.base importa todos los paquetes exportados de un módulo.
- JEP 512 finaliza Compact Source Files: un archivo .java puede correr sin declarar clase pública ni el main completo.
- JEP 521 activa el modo generacional de Shenandoah, el recolector de basura de baja pausa de Red Hat.
- Las cabeceras compactas se activan con -XX:+UseCompactObjectHeaders, todavía no vienen encendidas por defecto.
Qué es Java 25 y por qué es LTS
Java 25 salió el 16 de septiembre de 2025 y ya es la nueva versión con soporte a largo plazo (LTS), sucesora directa de Java 21. Las LTS reciben parches de seguridad y actualizaciones durante años, por eso son las que terminan corriendo en producción en la mayoría de empresas.
Oracle, Red Hat y Amazon Corretto ya publicaron sus builds basados en esta versión. La documentación completa de las mejoras vive en la página oficial del proyecto JDK 25.
Cabeceras de objeto compactas: menos memoria por instancia
El cambio más concreto de esta versión es JEP 519, cabeceras de objeto compactas. Hasta ahora, cada objeto en la JVM cargaba una cabecera de 96 bits en arquitecturas de 64 bits (128 bits si tenía puntero a array). Esa cabecera guarda el hash, los bits de bloqueo y el puntero a la clase del objeto. Con JEP 519, esa cabecera baja a 64 bits.
La función todavía no viene activada por defecto. Para probarla hay que arrancar la JVM con el flag correspondiente:
java -XX:+UseCompactObjectHeaders -jar aplicacion.jarPara confirmar si tu build de la JVM soporta el flag, corré java -XX:+PrintFlagsFinal -version | grep CompactObjectHeaders. Para medir el impacto real, comparás el uso de heap antes y después con jcmd <pid> GC.heap_info, ejecutando la misma carga de trabajo en ambos casos.
Scoped Values: alternativa inmutable a ThreadLocal
JEP 506 finaliza Scoped Values después de varias rondas de preview. Reemplazan a ThreadLocal para pasar datos de forma inmutable a través de una cadena de llamadas, incluyendo hilos virtuales. A diferencia de ThreadLocal, un Scoped Value no se puede reasignar dentro de su alcance y se libera automáticamente al salir del bloque.
final static ScopedValue<String> USUARIO_ACTUAL = ScopedValue.newInstance();
void procesarPeticion(String usuario) {
ScopedValue.where(USUARIO_ACTUAL, usuario).run(() -> {
atenderSolicitud();
});
}
void atenderSolicitud() {
System.out.println("Procesando para: " + USUARIO_ACTUAL.get());
}Esto evita fugas de memoria comunes con ThreadLocal en pools de hilos, donde un valor queda pegado al hilo aunque la tarea original ya haya terminado.
Module Import Declarations: importar un módulo completo
JEP 511 finaliza la sintaxis import module. En vez de escribir un import por cada paquete que usás de un módulo, podés importar todos los paquetes exportados de una vez:
import module java.base;
void main() {
List<String> lenguajes = List.of("Java", "Kotlin", "Scala");
lenguajes.forEach(System.out::println);
}Este ejemplo también usa JEP 512, Compact Source Files and Instance Main Methods, finalizado en esta versión: permite que un archivo .java corra sin declarar una clase pública ni escribir public static void main(String[] args) completo.
Shenandoah generacional: pausas más cortas en el recolector
JEP 521 saca del modo experimental a la versión generacional de Shenandoah, el recolector de basura de baja pausa de Red Hat. Divide el heap en una generación joven y una vieja, igual que hace G1, para recolectar con más frecuencia los objetos de vida corta sin escanear todo el heap en cada ciclo.
Qué significa para los desarrolladores
La mayoría de estos cambios no rompen código existente: Scoped Values y Compact Source Files son adiciones, no reemplazos obligatorios. La excepción es Compact Object Headers, que sigue siendo un flag opt-in porque puede chocar con herramientas que leen la memoria del objeto directamente, como algunos agentes de profiling y depuradores de bajo nivel. Antes de activarlo en producción conviene correrlo primero contra el set de pruebas de carga.
Conclusión
Java 25 es la LTS que va a correr en la mayoría de los servidores empresariales durante los próximos años, como pasó con Java 21 y Java 17 antes. Ninguno de estos cambios es disruptivo por sí solo, pero juntos apuntan a la misma dirección: menos memoria por objeto y menos fricción para trabajar con concurrencia estructurada.