¿Técnica o utilidad para minimizar el tiempo de “calentamiento” de Java?

Apoyo una aplicación de mensajería Java que requiere baja latencia (<300 microsegundos procesando cada mensaje). Sin embargo, nuestro perfil muestra que la máquina virtual Sun Java se ejecuta lentamente al principio, y se acelera después de los primeros 5.000 mensajes más o menos. Los primeros 5,000 mensajes tienen una latencia de 1-4 milisegundos. Después de aproximadamente los primeros 5.000, los mensajes posteriores tienen una latencia de ~ 250 microsegundos, con valores atípicos ocasionales.

En general se entiende que este es el comportamiento típico de una aplicación Java. Sin embargo, desde el punto de vista empresarial no es aceptable decirle al cliente que tiene que esperar a que la JVM se “caliente” antes de ver el rendimiento que exige. La aplicación debe ser “calentada” antes de procesar el primer mensaje del cliente

La JVM es Sun 1.6.0 actualización 4.

Ideas para superar este problema:

  1. Configuraciones de JVM, como -XX: CompileThreshold =
  2. Agregue un componente para “calentar” la aplicación al inicio, por ejemplo, enviando “mensajes falsos” a través de la aplicación.
  3. Cargue de forma estática las clases de aplicación y JDK al inicio de la aplicación, para que las clases no se carguen desde los JAR mientras procesan los mensajes de los clientes.
  4. Alguna utilidad o agente de Java que logre una o ambas de las dos ideas anteriores, de modo que no tenga que reinventar la rueda.

NOTA: Obviamente para esta solución estoy viendo todos los factores, incluyendo el arco de chips, el tipo de disco y la configuración del sistema operativo. Sin embargo, para esta pregunta, quiero centrarme en lo que se puede hacer para optimizar la aplicación Java y minimizar el tiempo de “calentamiento”.

“Calentamiento” en Java generalmente se trata de dos cosas:

(1): Carga de clases diferidas: esto puede ser un problema obligándolo a cargar.

La manera más fácil de hacerlo es enviar un mensaje falso. Debe asegurarse de que el mensaje falso active todo el acceso a las clases. Por ejemplo, si envía un mensaje vacío pero su progtwig verificará si el mensaje está vacío y evitará hacer ciertas cosas, entonces esto no funcionará.

Otra forma de hacerlo es forzar la inicialización de clases accediendo a esa clase cuando se inicia el progtwig.

(2): La optimización en tiempo real: en tiempo de ejecución, Java VM optimizará alguna parte del código. Esta es la razón principal por la cual hay un tiempo de calentamiento en absoluto.

Para facilitar esto, puede enviar un montón de mensajes falsos (pero se ven reales) para que la optimización pueda finalizar antes de que su usuario la use.

Otro que puede ayudar a facilitar esto es admitir en línea, como el uso privado y final tanto como sea posible. la razón es que, la máquina virtual no necesita buscar la tabla de herencia para ver qué método se va a llamar realmente.

Espero que esto ayude.

Su problema no es la carga de clases, sino la comstackción “just in time”.

Pruebe -XX:CompileThreshold=1

Eso obligará a Java a comstackr todo la primera vez que lo ejecute. Disminuirá un poco el inicio de su código, pero no el código VM (ya que se comstack cuando Java está instalado). Hay un error abierto para permitir que Java compile JAR personalizados de una manera similar y guarde el resultado para las ejecuciones posteriores, lo que reduciría en gran medida esta sobrecarga, pero no hay presión para solucionar este error en el corto plazo.

Una segunda opción sería enviar 5,000 mensajes falsos a la aplicación para “calentarla”. Vender esto como “asegurarse de que todo esté configurado correctamente”.

[EDITAR] Información de fondo en las clases de precomstackción: intercambio de datos de clase

Es posible que desee probar la versión de Java de IBM, ya que aquí puede agregar más clases al grupo compartido: descripción general del intercambio de datos de clase

[EDIT2] Para responder a las preocupaciones planteadas por kittylyst : Es cierto que esto llenará rápidamente su caché de código con métodos que se utilizan una sola vez. Y puede incluso hacer que toda tu aplicación sea más lenta.

Si lo configura en un valor bajo, el tiempo de inicio de su aplicación puede ser terriblemente lento. Esto se debe a que la optimización JIT + ejecutar el código comstackdo es más costosa que ejecutar el código una vez en el modo interpretado.

El principal problema aquí es que el código todavía se comstack “justo a tiempo”. Siempre que no puedas ejecutar todos los métodos que necesites al menos una vez, la aplicación “boostá” durante unos milisegundos cada vez que encuentre algo que no se haya comstackdo antes.

Pero si tiene la memoria RAM, su aplicación es pequeña o puede boost el tamaño de la memoria caché de código y no le importa el tiempo de inicio lento, puede intentarlo. En general, la configuración predeterminada es bastante buena.

Simplemente ejecute un montón de mensajes no operativos a través del sistema antes de que se abra para el tráfico genuino de clientes. 10k mensajes es el número habitual.

Para las aplicaciones financieras (por ejemplo, FIX), esto a menudo se realiza mediante el envío de pedidos (a un precio muy por debajo del cierre de la noche anterior, por las dudas) al mercado antes de que se abra. Todos serán rechazados, pero eso no importa.

Si el protocolo que está utilizando es homebrew, la próxima vez que actualice las bibliotecas para él, agregue soporte explícito para un tipo de mensaje “WARMUP” o “TEST” o “SANITYCHECK”.

Por supuesto, es probable que esto no compile las rutas específicas de la aplicación, pero en una aplicación de mensajería decente, la parte que trata con el tráfico de la red casi con seguridad será la parte dominante de la stack, así que eso no importa.

¿Estás usando el cliente o el servidor JVM? Intenta comenzar tu progtwig con:

 java -server com.mycompany.MyProgram 

Al ejecutar la JVM de Sun en este modo, el JIT comstackrá el bytecode en el código nativo antes; debido a esto, el progtwig tardará más tiempo en comenzar, pero se ejecutará más rápido después de eso.

Referencia: Preguntas frecuentes sobre Java HotSpot VM

Citar:

¿Cuál es la diferencia entre los sistemas -client y -server?

Estos dos sistemas son binarios diferentes. En esencia, son dos comstackdores diferentes (JIT) que interactúan con el mismo sistema de tiempo de ejecución. El sistema del cliente es óptimo para aplicaciones que requieren tiempos de inicio rápidos o pequeñas huellas, el sistema del servidor es óptimo para aplicaciones donde el rendimiento general es más importante. En general, el sistema del cliente es más adecuado para aplicaciones interactivas como GUI. Algunas de las otras diferencias incluyen la política de comstackción, los valores predeterminados del montón y la política de incorporación.

Si se ejecuta en el modo de servidor de Hotspot en hardware contemporáneo (con 2 o más núcleos por CPU) y con la última versión de JDK, la siguiente opción se puede utilizar para acelerar el calentamiento:

 -server -XX: + TieredComstacktion

Viejo hilo, lo sé, pero encontré esto en internet:

Algo muy interesante es la influencia de la opción XX: CompileThreshold = 1500 a SUN HotSpot JVM. El valor predeterminado es 10000 para Server VM y 1500 para Client VM. Sin embargo, establecerlo en 1500 para VM del servidor lo hace más rápido que la máquina virtual del cliente. Establecerlo a 100 realmente reduce el rendimiento. Y usar la opción Xcomp (lo que significa que todo el código se comstack antes del uso) ofrece un rendimiento aún menor, lo que es sorprendente.

Ahora sabes qué hacer.

Parece que su proyecto se beneficiaría de las garantías en tiempo real:

Ver: Java en tiempo real