es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

El agente de Java empaquetado como fatjar funciona lentamente con JDK8.

Estamos utilizando un agente Java para mejorar algunos métodos de la aplicación. El agente depende de otros archivos jar, y para mayor comodidad los empaquetamos junto con las dependencias en un fatjar, y luego cargamos los archivos jar dependientes a través de un cargador de clases personalizado. El programa puede iniciarse normalmente pero muy lentamente, y tarda unos minutos en iniciarse por completo. (Conté el tiempo de carga de cada clase (loadclass () en ClassLoader) y descubrí que la carga de algunas clases lleva cientos de milisegundos). De manera similar, cuando usé Spring Boot (también fatjar con las mismas dependencias), fue mucho más rápido.

La versión de JDK es 1.8.0_261.

El método premain es el siguiente:

public static void premain(String args, Instrumentation instrumentation) throws Exception {
final AgentLanucher agentLauncher = new AgentLanucher(); //—-1
agentLauncher.launch(); //—-2

// add transformer
instrumentation.addTransformer(new CustomAgentTransformer());

}

Y el código de AgentLauncher es el siguiente:

import org.springframework.boot.loader.JarLauncher;
public class AgentLanucher extends JarLauncher {
@Override
protected void launch(String[] args) throws Exception{
super.launch(args);
}
}

Cuando se ejecuta el código marcado con (1,2), la carga de una clase lleva mucho tiempo (decenas o cientos de milisegundos). El código para contar el tiempo de carga de una clase es el siguiente:

@Override
protected Class loadClass(String name, boolean resolve) throws ClassNotFoundException{
final long start = System.currentTimeMillis();
final Class clazz = super.loadClass(name, resolve);
final long end = System.currentTimeMillis();
System.out.println(“Load [” + name + “] : ” + (end -start));
return clazz;
}

Y descubrí que cuando el programa se ejecuta con JDK11, se ejecuta rápidamente. Luego cambié la versión de vuelta a JDK8, pero moví el código del premain a un hilo separado, y también se ejecutó rápidamente. El código es el siguiente:

public static void premain(String args, Instrumentation instrumentation) {
CompletableFuture.runAsync(() ->{
final AgentLauncher launcher = new AgentLauncher();
launcher.launch();
instrumentation.addTransformer(new CustomAgentTransformer());
});
}

Hay otro intento, bloqueé el hilo principal hasta que el sub-hilo completó. Se ejecutó lentamente. El código es el siguiente:

public static void premain(String args, Instrumentation instrumentation) {
final CompletableFuture initTask = CompletableFuture.runAsync(() -> {
final AgentLauncher launcher = new AgentLauncher();
launcher.launch();
instrumentation.addTransformer(new CustomAgentTransformer());
});
System.out.println(“Waiting…..”);
initTask.join();
}

Estoy confundido acerca del problema, gracias por cualquier ayuda.

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Explicación del problema con el tiempo de arranque lento del agente Java

    El problema es que el agente Java y sus dependencias están empaquetados en un fatjar y se cargan a través de un cargador de clases personalizado. Esto provoca un lento tiempo de arranque de la aplicación, ya que la carga de algunas clases tarda cientos de milisegundos.

    Una posible razón del lento tiempo de arranque es que el ClassLoader carga todas las clases del fatjar a la vez, en lugar de cargarlas bajo demanda, lo que provoca un retraso en el tiempo de arranque.

    Otra razón podría ser debido a la versión de JDK que se está utilizando. Cuando se ejecuta la aplicación con JDK 11, se ejecuta rápidamente, pero cuando se ejecuta con JDK 8, se ejecuta lentamente. Esto podría deberse a las mejoras de rendimiento en JDK 11 en comparación con JDK 8.

    Además, cuando el código en el método premain se mueve a un hilo separado, o el hilo principal se bloquea hasta que se complete el sub-hilo, el tiempo de arranque es más rápido. Esto sugiere que el lento tiempo de inicio podría deberse al bloqueo del hilo principal durante la carga del fatjar y sus dependencias.

    Se recomienda optimizar la carga del fatjar y sus dependencias, ya sea cargando las clases bajo demanda o utilizando un enfoque diferente por completo. Además, la actualización a una versión posterior de JDK también puede ayudar a mejorar el rendimiento.

Comments are closed.