JDK 28 integrará compilación anticipada de código para reducir tiempos de arranque

noticias programacion

La próxima versión del JDK incluirá JEP 544 (compilación anticipada de código), que promete reducir significativamente los tiempos de inicio y calentamiento. También se avanzará en las mejoras de ZGC para optimización de arranque y ajuste adaptativo de heap.


El ecosistema Java se prepara para uno de los cambios más significativos en la historia reciente de la JVM. JEP 544 (Ahead-of-Time Code Compilation) ha sido elevado a la fase Proposed to Target y está confirmado como objetivo de JDK 28.

Este JEP introduce, por primera vez en HotSpot, un mecanismo de compilación anticipada de código de aplicación a código nativo, con el objetivo de reducir drásticamente los tiempos de arranque y calentamiento que históricamente han lastrado a Java frente a alternativas como Go o Rust.

A esta iniciativa se suman dos JEP complementarios (JEP 545 y JEP 546) que abordan el mismo problema desde la perspectiva del recolector de basura ZGC, optimizando la adquisición de memoria durante el arranque y permitiendo un ajuste adaptativo del heap en tiempo de ejecución.

En conjunto, JDK 28 representa el esfuerzo más ambicioso hasta la fecha para resolver uno de los problemas estructurales de la plataforma.

JEP 544: compilación anticipada de código en HotSpot

¿Qué propone exactamente?

JEP 544 propone mejorar los tiempos de arranque y calentamiento haciendo que el código nativo optimizado de una aplicación esté disponible instantáneamente cuando la JVM HotSpot se inicia. El mecanismo es conceptualmente sencillo pero técnicamente complejo:

  1. Ejecución de entrenamiento (training run): La aplicación se ejecuta en un entorno controlado mientras la JVM compila el código de la aplicación a código nativo. El perfil de ejecución resultante identifica los métodos que más se benefician de la compilación anticipada.

  2. Almacenamiento en caché AOT: El código nativo generado se almacena en una caché AOT (AOT cache), un artefacto que puede ser reutilizado en ejecuciones posteriores.

  3. Ejecución de producción: Cuando la aplicación arranca en producción, la JVM carga la caché AOT y dispone inmediatamente del código nativo optimizado, sin necesidad de esperar a que el compilador JIT identifique y compile los puntos calientes durante la ejecución.

El resultado es que la aplicación alcanza su rendimiento máximo en una fracción del tiempo que requiere actualmente, eliminando la fase de “calentamiento” en la que el código interpretado y la compilación progresiva penalizan las primeras miles de ejecuciones.

El problema que resuelve

Java ha sido históricamente criticado por su tiempo de arranque y su fase de calentamiento. En comparación con lenguajes compilados de forma nativa como Go, C++ o Rust, una aplicación Java tarda más en alcanzar su rendimiento óptimo porque la JVM debe:

  • Interpretar el bytecode inicialmente.
  • Identificar los métodos “calientes” mediante el perfilado de ejecución.
  • Compilar esos métodos a código nativo con el compilador JIT (C1 y C2).
  • Optimizar progresivamente el código compilado a medida que se recopila más información.

Este ciclo, aunque produce código altamente optimizado a largo plazo, introduce una latencia inicial significativa que es problemática en escenarios como funciones serverless, contenedores efímeros, microservicios con escalado dinámico y aplicaciones CLI.

Relación con Project Leyden

JEP 544 es el producto más visible de Project Leyden, la iniciativa de OpenJDK cuyo objetivo es mejorar los tiempos de arranque, el rendimiento hasta el pico de velocidad y la huella de Java.

Leyden no busca eliminar la JVM ni sustituirla por una compilación totalmente estática (como hace GraalVM Native Image), sino añadir capacidades de compilación anticipada como una capa opcional sobre el modelo existente.

Esta distinción es importante: JEP 544 no convierte a Java en un lenguaje compilado estáticamente. La JVM sigue siendo dinámica, sigue usando JIT en tiempo de ejecución, y sigue soportando reflexión, carga dinámica de clases y todas las capacidades que hacen de Java una plataforma flexible. La caché AOT es una optimización de arranque, no un reemplazo del modelo de ejecución.

ZGC en JDK 28: arranque más rápido y heap adaptativo

Mientras JEP 544 ataca el problema desde la compilación, JEP 545 y JEP 546 lo abordan desde la gestión de memoria. Ambos JEP están dirigidos por Erik Österlund y han sido elevados a Proposed to Target para JDK 28.

JEP 545: arranque y calentamiento más rápidos con ZGC

El problema que aborda JEP 545 es sutil pero significativo. ZGC, el recolector de basura de baja latencia introducido en JDK 15, tiene una característica particular: la adquisición y preparación de memoria física del sistema operativo es una operación costosa. Esto crea una tensión entre el tamaño inicial del heap y los tiempos de arranque y calentamiento:

  • Heap inicial pequeño: arranque rápido, pero calentamiento lento, porque ZGC debe adquirir memoria de forma incremental a medida que la aplicación la demanda.
  • Heap inicial grande: arranque lento, pero calentamiento rápido, porque ZGC adquiere y prepara más memoria por adelantado antes de que la aplicación comience.

Los datos son contundentes: en hardware actual, la JVM HotSpot con ZGC arranca en aproximadamente una décima de segundo con un heap inicial de 2 MB, pero requiere más de diez segundos con un heap inicial de 32 GB. Esta diferencia de dos órdenes de magnitud es la que JEP 545 busca eliminar.

La propuesta de JEP 545 es revolucionaria en su simplicidad: ZGC debería ser capaz de expandir el heap rápidamente desde megabytes hasta terabytes mientras preserva la baja latencia durante el arranque, el calentamiento y más allá. Para lograrlo, el JEP introduce tres cambios clave:

  1. Solicitud inicial de solo 2 MB de heap por defecto: la JVM arranca con una huella de memoria mínima, lo que acelera el tiempo hasta la primera respuesta.
  2. Expansión agresiva del heap: a medida que la aplicación demanda memoria, ZGC la adquiere y prepara de forma agresiva, eliminando la penalización de calentamiento.
  3. Gestión de memoria en unidades de 2 MB en lugar de 4 KB: un cambio en la granularidad que reduce el overhead de gestión y acelera la preparación de memoria.

La consecuencia práctica de estos cambios es que dejará de ser necesario (o deseable) especificar -Xms, -Xmx o -XX:+AlwaysPreTouch . Basta con seleccionar ZGC y habilitar el ajuste adaptativo de heap:

java -XX:+UseZGC -XX:+ZAdaptiveHeapSizing ...

JEP 546: ajuste adaptativo del heap para ZGC

JEP 546 complementa a JEP 545 permitiendo que ZGC ajuste dinámicamente el tamaño del heap en función de tres factores: los recursos disponibles en el sistema, las necesidades de la aplicación y las necesidades de otras aplicaciones que compiten por los mismos recursos en el mismo host .

El problema que resuelve es profundo. La JVM presenta la ilusión de un heap infinito, pero esa ilusión debe implementarse con la memoria física finita de la máquina. ZGC usa tanta memoria como puede hasta el límite máximo configurado, porque un heap más grande significa ciclos de recolección menos frecuentes y por tanto, menor uso de CPU . El problema es que elegir el tamaño máximo óptimo del heap es notoriamente difícil:

  • Requiere comprender en profundidad el comportamiento de la aplicación.
  • Exige experimentar con diferentes tamaños en entornos representativos.
  • Los resultados no son portables entre configuraciones de hardware.
  • Deben repetirse cada vez que la aplicación o la JVM se actualizan.

Un tamaño de heap mal elegido tiene consecuencias adversas: si es demasiado pequeño, ZGC consume más CPU en recolecciones frecuentes y la aplicación puede quedarse sin memoria; si es demasiado grande, se desperdicia memoria que otras aplicaciones o el sistema operativo podrían necesitar.

JEP 546 propone que ZGC monitoree continuamente el uso de recursos del sistema, del contenedor y de la propia JVM, y ajuste el tamaño del heap en consecuencia . El objetivo es ofrecer el mismo rendimiento y latencia que un heap configurado manualmente de forma óptima, pero sin requerir intervención humana.

Estado de la funcionalidad: El ajuste adaptativo de heap se habilita con -XX:+ZAdaptiveHeapSizing y estará desactivado por defecto en JDK 28, con la intención de activarlo por defecto en una versión posterior para facilitar una transición gradual.

El contexto competitivo: GraalVM Native Image y la amenaza de los runtimes nativos

Para entender la importancia de JDK 28, es necesario situarlo en el contexto competitivo del ecosistema Java. GraalVM Native Image ha sido durante años la principal respuesta a los problemas de arranque de Java, ofreciendo compilación totalmente estática a código nativo que produce binarios con tiempos de arranque de milisegundos y huellas de memoria mínimas.

Sin embargo, GraalVM Native Image tiene costes significativos:

  • Pérdida de capacidades dinámicas: reflexión, proxies dinámicos, carga de clases en tiempo de ejecución y otras características de la JVM requieren configuración manual y tienen soporte limitado.
  • Tiempos de compilación largos: la compilación nativa puede tardar minutos u horas para aplicaciones grandes.
  • Ecosistema fragmentado: no todas las bibliotecas y frameworks soportan Native Image de forma nativa.
  • Curva de aprendizaje: requiere un conjunto de herramientas y configuraciones específicas que no forman parte del flujo de trabajo estándar de Java.

JEP 544 ofrece un enfoque diferente: compilación anticipada opcional sobre la JVM estándar. No requiere abandonar HotSpot, no pierde capacidades dinámicas y no fragmenta el ecosistema. Como señala el análisis de ej-technologies, JEP 544 podría marcar el fin del “monopolio de arranque de GraalVM”.

La distinción clave es que JEP 544 no compite con GraalVM Native Image en el mismo espacio: mientras Native Image produce binarios independientes sin JVM, la caché AOT de Leyden acelera el arranque de la JVM estándar. Son enfoques complementarios que atienden necesidades diferentes. Pero para la mayoría de aplicaciones que no pueden o no quieren adoptar Native Image, JEP 544 representa una alternativa mucho más accesible.

Hoja de ruta y disponibilidad

JDK 28 se encuentra actualmente en desarrollo, con JDK 27 ya disponible desde el 15 de septiembre de 2026 y JDK 28 previsto para marzo de 2027. Los JEP 544, 545 y 546 han alcanzado la fase Proposed to Target, lo que significa que el diseño está completo y el equipo de ingeniería está trabajando en su implementación. La revisión de JEP 544 se espera que concluya en septiembre de 2026, y la implementación ya tiene un pull request abierto en el repositorio de OpenJDK.

Como es habitual en el ciclo de Java, los desarrolladores podrán probar estas funcionalidades en las builds de acceso temprano de JDK 28 antes de su lanzamiento oficial. Dado que JDK 28 será una versión no LTS, su adopción en producción estará limitada a equipos que sigan el ciclo de innovación, pero marcará el camino que las futuras versiones LTS incorporarán.

Limitaciones y consideraciones

A pesar del entusiasmo que generan estos JEP, conviene señalar varias limitaciones y preguntas abiertas:

1. La caché AOT requiere una ejecución de entrenamiento

La compilación anticipada no es gratuita ni automática. Requiere configurar y ejecutar un entrenamiento que genere la caché AOT, un paso adicional en el ciclo de vida de despliegue que introduce complejidad operativa. Las aplicaciones cuya carga de trabajo varía significativamente entre ejecuciones pueden beneficiarse menos de una caché entrenada con un perfil específico.

2. Compatibilidad con JIT y perfiles de ejecución

La caché AOT está diseñada para complementar, no reemplazar, al compilador JIT. Los métodos compilados de forma anticipada siguen sujetos a recompilación y desoptimización si el perfil de ejecución en producción difiere del de entrenamiento. En aplicaciones con patrones de uso muy variables, el beneficio puede ser menor del esperado.

3. El ajuste adaptativo de heap está desactivado por defecto

JEP 546 no estará activo por defecto en JDK 28. Los usuarios que quieran beneficiarse del ajuste dinámico de heap deberán habilitarlo explícitamente con -XX:+ZAdaptiveHeapSizing. Esto limita el impacto inmediato del cambio, aunque es una decisión prudente para permitir una transición gradual.

4. JEP 544 no está en JDK 27

Quienes esperaban ver estas mejoras en JDK 27 deben saber que JEP 544 no forma parte de esa versión. La compilación anticipada completa está reservada para JDK 28 .
o o GraalVM Native Image.

Vistas: 3

Descubre más desde CIBERED

Suscríbete y recibe las últimas entradas en tu correo electrónico.

Scroll al inicio