Skip to content

Class Data Sharing en Java

A fin de optimizar el tiempo de arranque de la máquina virtual de Java y reducir el uso de memoria se puede crear un fichero que contenga un conjunto de clases precompiladas. Este fichero almacena las clases en un formato de representación interna que puede cargarse directamente en memoria, y que además, por ser de sólo lectura y mapeado en memoria, es automáticamente compartido por las distintas máquinas virtuales que se encuentren levantadas a un mismo tiempo. Esta opción se llama Class Data Sharing (CDS).

Un fichero de este tipo se crea automáticamente cuando se instala Java desde el programa de instalación en Windows con las clases básicas de Java. Pero si la instalación se realiza descomprimiendo el programa de instalación manualmente, o copiándola de un directorio ya existente, entonces el fichero hay que crearlo con el siguiente comando:

Como resultado de la ejecución del comando se muestra un log muy detallado que en la mayoría de los casos se puede ignorar, aunque hay algún dato informativo útil, como por ejemplo el número de clases añadidas al fichero:
    Number of classes 1298
El fichero generado se llama classes.jsa  y se crea en el subdirectorio /bin/server. Si ya existe se sobreescribe.

La máquina virtual de Java tiene un comportamiento definido por defecto con respecto al uso del fichero. No obstante, existe un parámetro que puede utilizarse para deshabilitar o forzar su uso. -Xshare:off fuerza que no se utilice el fichero, -Xshare:on fuerza que se utilice, y -Xshare:auto aplica el comportamiento por defecto.

Debido al que el formato del fichero depende de la arquitectura de cada máquina en concreto, se puede utilizar -Xshare:on para comprobar que el fichero es válido, y no se ha copiado por ejemplo desde una máquina con Windows a otra con Linux. Con -Xshare:on Java no arrancará si el fichero no es válido. Con el comportamiento por defecto Java ignorará el fichero si no es válido.

Además de las clases básicas de Java añadidas al fichero, Java 10 permite crear ficheros personalizados con las clases precompiladas que se quieran. Opción a la que Oracle ha llamado Application Class-Data Sharing (ApsCDS), y que se implementa utilizando un fichero que contenga un listado con el nombre de las clases que se quieran precompilar.

No obstante, antes de crearlo es interesante entender como probar y verificar el origen de cada clase en Java. Para ello se puede utilizar el parámetro que activa el log en la máquina virtual de Java. Por ejemplo, para ver desde donde se cargan las clases si no se utiliza CDS se puede ejecutar el siguiente comando:

En la salida se mostrará cada clase cargada y su origen. Y puede verse que la clase java.lang.Object, y todas las demás, se cargan desde el jar del runtime:

    java.lang.Object source: jrt:/java.base

En cambio, si se fuerza el uso de CDS:

en la salida puede comprobarse que  ahora java.lang.Object, y todas las demás, se cargan desde el fichero compartido:
    java.lang.Object source: shared objects file
Una vez realizada esta comprobación, ya se puede crear una aplicación de prueba con objetivo de añadir sus clases a un fichero compartido que la máquina virtual pueda precargar:

Aplicación que se puede compilar, empaquetar en un jar, y probar de la forma acostumbrada con los siguientes comandos:

De forma que en la salida puede verse que la clase test.Test se carga desde Test.jar:

    test.Test source: file:<path>/test/Test.jar

Para obtener un fichero con las clases cargadas por la aplicación de prueba se debe ejecutar el siguiente comando:

El parámetro -XX:+UnlockCommercialFeatures es necesario sólo si se está utilizando la máquina virtual de Oracle, y no requiere ningún tipo de licencia en contra de lo que el nombre parece sugerir. -XX:+UseAppCDS activa la opción de AppCDS. Y -XX:DumpLoadedClassList especifica el fichero donde se deben de volcar los nombres de las clases cargadas por la aplicación. El fichero generado es un fichero de texto plano con una línea por cada clase.

El siguiente paso es crear un fichero con las clases precompiladas a partir del fichero de clases generado en el paso anterior:

El parámetro -XX:SharedClassListFile indica el fichero con el listado de clases a utilizar, y -XX:SharedArchiveFile especifica el fichero con las clases precompiladas a crear.

El último paso es volver a lanzar la aplicación de prueba forzando que se utilice el fichero con las clases compartidas creado en el paso anterior:

En la salida puede verse que ahora la clase de la aplicación de pruebas se carga desde el fichero compartido:

    test.Test source: shared objects file

Este procedimiento debería realizarse, y automatizarse, para las aplicaciones y servidores de aplicaciones, con el objetivo de disminuir el tiempo de arranque y la memoria utilizada cuando se encuentren en ejecución varias máquinas virtuales al mismo tiempo.

Java 10

Oracle cambió recientemente la política de publicación de nuevas versiones de Java. Ahora los ciclos de vida serán más cortos, se añadirán nuevas características de manera más frecuente, se publicará una nueva versión cada seis meses con un periodo de soporte reducido, y sólo una de cada tres versiones tendrán un periodo de soporte prolongado o “long term support” (LTS).

La versión LTS actual es la 8, y la próxima será la 11 a ser publicada en septiembre. La versión 9 y 10 pueden verse como versiones intermedias para experimentar con las nuevas características.

Este intento de dinamizar el desarrollo e incorporación de nuevas características trata de igualar Java a otros lenguajes, como JavaScript, para el que la competencia entre navegadores ha supuesto una evolución muy rápida en los últimos años, y evitar perder la batalla del Internet de las Cosas (IOT).

La versión 9 de Java salió apenas hace seis meses repleta de novedades, que la mayoría de los equipos de desarrollo aún no han empezado a conocer y explotar, pero cumpliendo con el calendario propuesto, Oracle ya ha publicado la versión 10.

Las novedades destacadas por la propia Oracle son:

  • Inferencia de tipos de variables locales
  • Mejora del Garbage Collector G1 haciéndolo completamente paralelo
  • Ampliación de Class-Data Sharing para permitir la inclusión de clases de aplicación
  • Activación del compilador JIT en plataformas Linux de 64 bits

Leyendo entre líneas, además de las habituales mejoras de rendimiento, es claro que las novedades van enfocadas a mejorar la experiencia de desarrollo para equipararla a lenguajes de script como JavaScript o Dart. Reduciendo la cantidad de código a escribir, con la introducción de la palabra reservada var para la inferencia de tipos. Dando pasos hacia una compilación Ahead Of Time (AOT) eficiente. Y la creación de snapshots para reducir los tiempos de arranque.

Para instalar la nueva versión en Windows basta con descargar el ejecutable y ejecutarlo de la forma acostumbrada. No obstante, si se tiene varias máquinas virtuales instaladas a la vez, y se quiere controlar de forma precisa cuál de ellas se ejecuta en cada momento, lo recomendable es abrir jdk-10_windows-x64_bin.exe con 7-Zip o similar, extraer el fichero tools.zip, y descomprimir este último en un directorio concreto donde se quiere tener la máquina virtual instalada.

El proceso de extracción de la máquina virtual a un directorio desde el ejecutable se ha simplificado con respecto a la versión 8, y algunas de las anteriores, que requería más pasos e implicaba el uso de unpack200 para descomprimir.

Una vez instalada la nueva versión se puede verificar la instalación desde línea de comandos ejecutando java –version, lo que retorna la siguiente salida:

La nomenclatura utilizada para identificar la máquina virtual es distinta con respecto a anteriores versiones. Aunque se sigue conservando la numeración original, ahora se utiliza el año y mes de publicación para distinguir las versiones. La cadena 18.3 hace referencia a marzo de 2018.

Revamped

He actualizado el blog. Lo principal ha sido sustituir Drupal por WordPress, principalmente por que este último tiene actualizaciones automáticas. Y por lo demás ha sido un cambio de aspecto bastante moderado. He conservado el estilo parco del anterior, sin muchas florituras.

Todas las entradas del blog y las páginas de artículos se han migrado correctamente en la mayoría de los casos, respectando las urls originales cuando ha sido posible. Lo único que se ha perdido son los comentarios.

Aún quedan detalles que ir corrigiendo, como algún texto que sale en inglés, porque el tema no lo traduce, y algunas imágenes que se salen por los márgenes, pero poca cosa en general. Me queda dar un repaso general a todo el contenido (unas 700 páginas individuales) para ir solventando detalles.

He redirigido todo el tráfico al nuevo software, eliminado el anterior, y añadido un par de plugins para mi comodidad, como el del captcha por ejemplo, para evitar el spam en los comentarios.

¡A ver si aguanta otros 11 años!

10 años en la red

Pues sí, diez años lleva ya esta web en marcha. El último año en blanco, pero de forma intencionada, quería ver si pasado ese tiempo volvería a seguir teniendo ganas de escribir algo, y si tendría algún plan nuevo para la web. Y aquí estoy, escribiendo y con algún que otro plan ya en marcha.

Lo primero que tendría que hacer es cambiar el software con el que funciona la web. Hace mucho tiempo que no actualizo la versión de Drupal (el CMS que utilizo para el blog), y las últimas subidas de versión de PHP y MySQL de mi servidor de hosting hacen que algunas partes de la web, sobre todo de la parte interna de administración y alguna pública como los comentarios, no funcionen ya correctamente.

Mi principal requerimiento es no tener que actualizar manualmente el software del CMS para aplicarle parches de seguridad y actualizaciones importantes, algo que Drupal no soporta de forma nativa y no parece que vaya a soportar en un futuro próximo. Por lo que he estado sopesando un par de opciones. La primera era migrar a una plataforma externa en vez de tener un servidor propio, tipo blogger.com o wordpress.com. Incluso he montado un par de blogs de ejemplo en estas plataformas para ver las interfaces de usuario. La segunda era usar otro software, como el propio WordPress que si se actualiza automáticamente. Incluso he instalado ya una versión en mi servidor de hosting para ver el rendimiento y el panel de administración.

La opción de usar una plataforma externa la he descartado porque el objetivo de esta web siempre fue aprender a base de instalar, usar y adaptar el software según mi necesidad o capricho. Tener el software instalado en otro servidor sin posibilidad de modificarlo hace que el mantenimiento sea prácticamente nulo, pero me limita a la hora de realizar cambios a mi antojo para probar cosas nuevas.

Así que la opción de instalar un nuevo software era la opción más lógica. Lo que hay que hacer sin embargo lleva más tiempo. Instalar el software, configurar las opciones de administración, instalar plugins, elegir un tema, configurar el tema, importar el contenido del blog actual, revisar la importación, desactivar Drupal y activar WordPress.

Blogger
En la imagen que acompaña a este post está una prueba de concepto del estilo que quiero aplicar al blog. Algo muy sencillo en realidad. Los borrones de tinta es de una imagen de fondo de blogger, y que no creo que utilice.

Hay miles de temas disponibles para WordPress y siempre parece que hay alguno que te encaja pero le faltan un par de opciones que te gustaría tener. Al final me veo modificando una plantilla, como de costumbre, algo que querría evitar a toda costa para que las actualizaciones sean más sencillas en el futuro. Probablemente sea la parte que más tiempo me lleve, junto con la migración, ya que me gustaría respetar las urls originales para que no se pierdan todos los enlaces a las páginas ya existentes.