Por Canuto  

Java 27 llega con una actualización poco vistosa, pero con efectos concretos: reduce el tamaño de los objetos, unifica G1 como recolector predeterminado, elimina secretos de ciertas grabaciones JFR y añade intercambio híbrido poscuántico en TLS 1.3. La versión también mantiene en evolución varias funciones de vista previa, desde constantes perezosas hasta concurrencia estructurada.
***

  • Las cabeceras compactas pasan a ser la configuración predeterminada y pueden reducir significativamente el consumo de memoria de los objetos pequeños.
  • G1 se convierte en el recolector de basura predeterminado incluso en entornos con una CPU y poca memoria, aunque Serial GC sigue disponible.
  • JFR incorpora redacción de variables sensibles y TLS 1.3 prioriza el intercambio híbrido X25519MLKEM768 cuando el otro extremo lo admite.


Java 27 avanza hacia su lanzamiento general previsto para el 15 de septiembre de 2026, después de alcanzar la fase de candidato de lanzamiento con un conjunto congelado de nueve JEPs desde el 4 de junio. La versión no busca deslumbrar con una única función de alto impacto, sino introducir cambios silenciosos que pueden modificar el consumo de memoria, el comportamiento del recolector de basura y la seguridad de las herramientas de diagnóstico. Una revisión de la compilación de acceso temprano mostró que buena parte de las novedades funciona sin cambios en el código existente.

El lanzamiento combina cuatro características finales con cinco propuestas que todavía permanecen en vista previa o incubación. Entre las primeras destacan las cabeceras compactas por defecto, G1 como recolector predeterminado en todos los entornos, la redacción de datos sensibles en Java Flight Recorder y el intercambio híbrido poscuántico para TLS 1.3. Las demás funciones continúan afinando APIs relacionadas con inicialización diferida, patrones sobre tipos primitivos, concurrencia estructurada, codificación PEM y operaciones vectoriales.

Menos memoria por objeto

JEP 534 convierte las cabeceras compactas de objeto en la configuración predeterminada de Java 27, tras haber pasado por una etapa experimental en JDK 24 y una integración productiva en JDK 25. En plataformas de 64 bits, el diseño tradicional utilizaba una palabra de marca de 64 bits y otra palabra de clase, con una cabecera habitual de 96 bits cuando los punteros de clase estaban comprimidos. El nuevo formato fusiona ambos elementos en una sola palabra de 64 bits.

La modificación importa porque las aplicaciones Java suelen manejar grandes cantidades de objetos pequeños, desde líneas de pedido hasta contenedores como Optional. El artículo técnico reporta una reducción de 22% en el uso de memoria y de 8% en CPU en SPECjbb 2015, además de 15% menos recolecciones de basura, mientras que usuarios tempranos de Project Lilliput observaron reducciones de entre 10% y 20% en el tamaño de datos de producción. El beneficio puede resultar especialmente visible en contenedores con límites de memoria difíciles de ampliar.

El diseño anterior reservaba ocho bytes para la palabra de marca y cuatro para el puntero comprimido de clase, antes de almacenar los campos y completar la alineación del objeto. Con el formato de JDK 27, el puntero de clase comprimido, limitado a 22 bits, se integra en la palabra compacta y los campos ocupan el espacio que antes correspondía a la segunda palabra de cabecera. En una clase Pair con dos enteros, el tamaño ilustrativo pasa de 24 a 16 bytes, sin perder la capacidad de utilizar System.identityHashCode().

El límite de tipos asociado al puntero de clase de 22 bits ronda los cuatro millones, de acuerdo con la explicación de la característica, y una aplicación que lo supere puede enfrentar un OutOfMemoryError durante la carga de clases. Java 27 mantiene temporalmente una vía de salida mediante -XX:-UseCompactObjectHeaders, aunque el plan del proyecto contempla retirar por completo el diseño heredado. Por ello, los equipos que actualicen deberían revisar tanto el tamaño real del heap como sus necesidades excepcionales de carga de clases.

G1 deja de depender del tamaño del entorno

JEP 540 cambia otra decisión que la máquina virtual tomaba automáticamente: Java 27 selecciona G1 como recolector de basura predeterminado sin importar si el entorno tiene una sola CPU o menos de 1.792 MB de memoria. Antes, esas condiciones podían activar Serial GC de manera silenciosa, algo frecuente en pods pequeños de Kubernetes y otros contenedores con límites ajustados. Una prueba con una CPU virtual y un heap máximo de 256 MB mostró que G1 seguía activo.

La decisión se apoya en los avances de rendimiento de G1 registrados en JDK 26, que redujeron la diferencia frente a Serial GC y conservaron un comportamiento favorable en materia de pausas. Sin embargo, el cambio no significa que Serial haya desaparecido ni que sea incorrecto para heaps muy pequeños, porque ese recolector puede ofrecer una huella nativa menor. Los administradores todavía pueden seleccionarlo explícitamente con -XX:+UseSerialGC cuando las pruebas de la carga de trabajo lo justifiquen.

El nuevo valor predeterminado exige observar el consumo total del proceso, no solo el tamaño configurado para el heap. G1 utiliza estructuras nativas, hilos de marcado y refinamiento, además de información adicional para administrar la memoria, de modo que un pod que ya opera al límite podría presentar un perfil RSS diferente después de actualizar. La recomendación práctica es comparar el comportamiento en producción antes de concluir que la reducción de objetos compensa todos los costos operativos.

Java 27 también modifica el tratamiento predeterminado de MinHeapFreeRatio y MaxHeapFreeRatio, que dejan de imponer el mismo control automático de expansión y contracción del heap. Además, InitiatingHeapOccupancyPercent adopta el nombre G1IHOP, aunque la opción anterior continúa funcionando temporalmente y muestra una advertencia de obsolescencia. Los equipos deberían localizar esos parámetros en sus archivos de despliegue y gráficos de Helm antes de que una futura versión elimine el alias antiguo.

JFR redacciona secretos antes de escribirlos

JEP 756 incorpora redacción de datos sensibles directamente en Java Flight Recorder, una herramienta que permite observar el rendimiento de aplicaciones en ejecución. Las grabaciones pueden incluir variables de entorno, propiedades del sistema y argumentos del programa, campos que con frecuencia contienen contraseñas, tokens o claves utilizadas durante el arranque. A partir de Java 27, la JVM reemplaza determinados valores por [REDACTED] antes de incorporarlos al archivo .jfr.

El filtrado predeterminado busca nombres que coincidan, sin distinguir mayúsculas y minúsculas, con patrones asociados a api key, autenticación, secretos de cliente, credenciales, contraseñas, claves privadas, tokens y términos similares. Los argumentos de programa reciben el mismo tratamiento, por lo que un parámetro como –db-password no debería exponer su valor en una grabación estándar. La medida reduce el riesgo de compartir diagnósticos con colegas o adjuntarlos a tickets sin una revisión manual exhaustiva.

Los desarrolladores pueden añadir convenciones propias mediante FlightRecorderOptions y redactar nombres específicos como ACCESS_TOKEN o cualquier variable que coincida con un patrón definido. También existe la posibilidad de reemplazar los filtros predeterminados, aunque esa configuración genera una advertencia para recordar que se desactivaron protecciones integradas; una sintaxis con none permite expresar el reemplazo de forma explícita. Esta flexibilidad resulta útil para organizaciones que utilizan nombres internos distintos de los patrones comunes.

La protección tiene un alcance deliberadamente limitado y se presenta como una función de mejores esfuerzos, no como una garantía de saneamiento completo. Cubre eventos de arranque relacionados con el entorno, las propiedades del sistema, la información de la JVM y los argumentos, pero no elimina datos de eventos de aplicación, mensajes de excepción ni comandos ejecutados por procesos hijos. Un archivo JFR será más seguro en Java 27, aunque todavía requiere controles de manejo y revisión antes de distribuirse.

TLS 1.3 incorpora una defensa frente a la computación cuántica

JEP 527 añade intercambio de claves híbrido poscuántico para TLS 1.3, en respuesta al riesgo conocido como recolectar hoy y desencriptar mañana. Bajo ese escenario, un atacante conserva tráfico cifrado capturado en el presente y espera disponer de una computadora cuántica capaz de romper mecanismos clásicos basados en curvas elípticas. El objetivo de la actualización es proteger desde ahora información cuyo período de confidencialidad podría extenderse durante décadas.

El mecanismo combina el intercambio ECDHE clásico con ML-KEM, un encapsulamiento de claves estandarizado por NIST que ya había llegado a Java. La conexión mezcla los dos secretos, de modo que un adversario tendría que comprometer ambos componentes para recuperar la sesión, mientras que el costo práctico consiste en mensajes de negociación más grandes. La clave pública de ML-KEM ocupa 1.184 bytes y el texto cifrado añade otros 1.088 bytes, según los datos incluidos en la descripción de la función.

El grupo híbrido X25519MLKEM768 pasa a ser priorizado por las conexiones TLS 1.3 realizadas mediante javax.net.ssl cuando el otro extremo lo admite. Si el servidor no soporta grupos híbridos, si la conexión utiliza TLS 1.2 o si la aplicación fija grupos específicos, la negociación continúa con el método disponible anteriormente. Esta compatibilidad gradual permite activar la protección sin exigir una modificación inmediata en cada aplicación o servidor.

La propuesta protege el intercambio de claves públicas, pero no convierte de inmediato las firmas de certificados en poscuánticas. Esa distinción es importante porque la prioridad de JEP 527 consiste en impedir que el tráfico capturado hoy pueda descifrarse en el futuro, mientras que la migración de firmas representa una frontera tecnológica posterior. La prueba completa también depende de que exista un servidor remoto compatible, por lo que el soporte visible para un desarrollador local puede variar.

Las funciones que todavía maduran

JEP 531 presenta la tercera vista previa de LazyConstant, una abstracción que calcula un valor como máximo una vez, en el primer uso, y permite que la JVM aproveche después la semántica de una constante. El modelo busca evitar el costo de inicializar ciertos valores durante la carga de una clase sin renunciar a una garantía de evaluación única. La API se encuentra en java.lang y también contempla fábricas perezosas para listas, mapas y, en esta ronda, conjuntos.

La inicialización diferida no depende únicamente de declarar una referencia como static final, porque la JVM solo puede tratarla como una constante permanente cuando accede a ella mediante una cadena de campos confiables y una forma canónica. Entre los cambios de la tercera vista previa desaparecen isInitialized() y orElse, señales de que la API continúa reduciendo sus superficies antes de una eventual estabilización. Para los usuarios, el comportamiento esencial permanece concentrado en crear la constante y llamar a get().

JEP 532 mantiene en su quinta vista previa los patrones que incorporan tipos primitivos a instanceof y switch. La propuesta permite tratar valores numéricos como participantes directos del patrón y aplica reglas de conversión exacta, por lo que un entero como 100 puede coincidir con byte cuando su representación no pierde información. En cambio, un literal double como 0,1 no coincide con float si la conversión implica pérdida de precisión.

La concurrencia estructurada de JEP 533 alcanza su séptima vista previa después de varios rediseños destinados a evitar que una API inmadura quede congelada durante décadas. Su modelo abre subtareas dentro de un ámbito, espera su finalización y utiliza try-with-resources para impedir que los trabajos escapen del alcance; si una subtarea falla, las hermanas pueden cancelarse. La ronda elimina FailedException, hace que join() utilice ExecutionException y ajusta tipos, tiempos de espera y sobrecargas de apertura.

JEP 538 conserva en su tercera vista previa la API para codificar y decodificar objetos criptográficos en formato PEM, con métodos que permiten trabajar con claves privadas y cifrado mediante contraseña. La revisión se concentra principalmente en renombrar elementos, mientras que el uso central mantiene una sintaxis breve frente al procedimiento tradicional de retirar encabezados, decodificar Base64 y construir una especificación PKCS8. El objetivo es convertir una tarea propensa a errores en una operación explícita de la biblioteca.

JEP 537 lleva la API vectorial a su duodécima incubación y continúa dependiendo del módulo jdk.incubator.vector tanto para compilar como para ejecutar. La herramienta permite expresar operaciones SIMD sobre especies de vectores preferidas, dejar que el compilador JIT las traduzca a instrucciones como AVX o NEON y procesar por separado los elementos finales que no completan un vector. Su estabilización sigue vinculada al modelo de clases de valor de Project Valhalla, por lo que una vista previa podría llegar cuando ese trabajo avance.

Otros ajustes y perspectiva para los equipos

Java 27 incorpora además cambios sin JEP propio que pueden afectar a aplicaciones específicas. Los formatos de fecha ISO 8601 aceptan ahora desplazamientos como +02, además del formato +02:00, lo que puede evitar rechazos inesperados en parsers que antes esperaban una representación más extensa. JVMCI, la interfaz de compiladores relacionada históricamente con Project Graal, sale del JDK después de aproximadamente una década, mientras GraalVM mantiene su implementación por separado.

La opción -XX:-UseCompressedClassPointers queda obsoleta como consecuencia natural de la evolución hacia cabeceras compactas de objeto. Aunque estos cambios no exigen necesariamente una intervención inmediata, sí justifican una revisión de banderas heredadas, scripts de arranque y documentación interna. Las aplicaciones que dependen de configuraciones muy específicas deberían validar sus imágenes de ejecución con la compilación final y no asumir que todos los valores anteriores conservarán el mismo papel.

El perfil de Java 27 es, por tanto, menos espectacular que el de una versión dominada por una API completamente nueva, pero más relevante para operaciones cotidianas. Una aplicación puede obtener objetos más pequeños, G1 como punto de partida común, diagnósticos con menor probabilidad de filtrar secretos y una negociación TLS 1.3 preparada para una transición poscuántica, todo sin reescribir sus clases. El precio de esa comodidad consiste en medir memoria nativa, revisar compatibilidad y probar los cambios de seguridad con los extremos remotos.

Las funciones de vista previa muestran una estrategia más gradual: constantes perezosas, patrones primitivos y concurrencia estructurada siguen recibiendo ajustes incluso después de varias rondas, mientras la API vectorial permanece en incubación. Esa cautela puede frustrar a quienes esperan estabilizaciones rápidas, pero reduce el riesgo de comprometer diseños de lenguaje y memoria durante décadas. Para los equipos técnicos, Java 27 ofrece una actualización silenciosa en producción y un laboratorio de capacidades futuras en desarrollo.


Imagen original de DiarioBitcoin, creada con inteligencia artificial, de uso libre, licenciada bajo Dominio Público.

Este artículo fue escrito por un redactor de contenido de IA y revisado por un editor humano para garantizar calidad y precisión.


ADVERTENCIA: DiarioBitcoin ofrece contenido informativo y educativo sobre diversos temas, incluyendo criptomonedas, IA, tecnología y regulaciones. No brindamos asesoramiento financiero. Las inversiones en criptoactivos son de alto riesgo y pueden no ser adecuadas para todos. Investigue, consulte a un experto y verifique la legislación aplicable antes de invertir. Podría perder todo su capital.

Suscríbete a nuestro boletín