Pregunta

¿Qué es lo que hace que la JVM (en particular, la implementación de Sun) funcione lentamente en comparación con otros tiempos de ejecución como CPython? Mi impresión fue que tiene que ver principalmente con una gran cantidad de bibliotecas que se cargan, ya sea que se necesiten o no, pero eso parece algo que no debería tomar 10 años para solucionarlo.

Ahora que lo pienso, ¿cómo se compara el tiempo de inicio de JVM con el CLR en Windows? ¿Qué tal el CLR de Mono?

ACTUALIZACIÓN: Me preocupa especialmente el caso de uso de pequeñas utilidades encadenadas, como es común en Unix. ¿Java es ahora adecuado para este estilo? Cualesquiera que sean los gastos generales de inicio de Java, ¿se suman para cada proceso de Java, o los gastos generales solo se manifiestan realmente para el primer proceso?

¿Fue útil?

Solución

Aquí está lo que Wikipedia tiene que decir sobre el tema (con algunas referencias) .

Parece que la mayor parte del tiempo se toma simplemente cargando datos (clases) del disco (es decir, el tiempo de inicio está vinculado a E / S).

Otros consejos

Solo para notar algunas soluciones:

Hay dos mecanismos que permiten un inicio más rápido de JVM. El primero, es el mecanismo de intercambio de datos de clase, que es compatible desde Java 6 Update 21 (solo hasta donde sé HotSpot Client VM, y solo hasta donde yo sé)

Para activarlo, debe configurar las opciones JVM -Xshare (en algunas implementaciones: -Xshareclasses ).

Para leer más sobre la función que puede visitar: Compartir datos de clase

El segundo mecanismo es un Java Quick Starter. Permite precargar clases durante el inicio del sistema operativo, consulte: Java Quick Starter para obtener más detalles.

Ejecutar una aplicación Java trivial con la JVM del cliente 1.6 (Java 6) parece instantánea en mi máquina. Sun ha intentado ajustar la JVM del cliente para un inicio más rápido (y la JVM del cliente es la predeterminada), por lo que si no necesita muchos archivos jar adicionales, el inicio debería ser rápido.

Si está utilizando Sun's HotSpot para x86_64 (compilado de 64 bits), tenga en cuenta que la implementación actual solo funciona en modo servidor, es decir, precompila cada clase que carga con optimización completa, mientras que la versión de 32 bits también admite el modo cliente, que generalmente pospone la optimización y optimiza solo las partes que requieren más CPU, pero tiene tiempos de arranque más rápidos.

Ver por ejemplo:

Dicho esto, al menos en mi máquina (Linux x86_64 con kernel de 64 bits), la versión HotSpot de 32 bits admite el modo cliente y servidor (a través de los indicadores -client y -server), pero el modo predeterminado es el modo servidor, mientras que el 64bit la versión solo admite el modo de servidor.

Realmente depende de lo que esté haciendo durante el inicio. Si ejecuta la aplicación Hello World, tarda 0,15 segundos en mi máquina.

Sin embargo, Java es más adecuado para ejecutarse como cliente o servidor / servicio, lo que significa que el tiempo de inicio no es tan importante como el tiempo de conexión (aproximadamente 0.025 ms) o el tiempo de respuesta del tiempo de ida y vuelta (< ; < 0.001 ms).

Hay varias razones:

  • muchos jar s para cargar
  • verificación (asegurarse de que el código no haga cosas malas)
  • JIT (compilación justo a tiempo) sobrecarga

No estoy seguro acerca del CLR, pero creo que a menudo es más rápido porque almacena en caché una versión nativa de ensamblajes para la próxima vez (por lo que no necesita JIT). CPython comienza más rápido porque es un intérprete y IIRC no hace JIT.

Además de las cosas ya mencionadas (clases de carga, especialmente de archivos JAR comprimidos); ejecuta en modo interpretado antes de HotSpot compila bytecode de uso común; y sobrecarga de compilación HotSpot, también hay bastante inicialización única realizada por las propias clases JDK. Muchas optimizaciones se realizan a favor de los sistemas de ejecución más larga donde la velocidad de inicio es menos preocupante.

Y en cuanto a la canalización de estilo Unix: ciertamente NO desea iniciar y reiniciar JVM varias veces. Eso no va a ser eficiente. Más bien, el encadenamiento de herramientas debería ocurrir dentro de JVM. Esto no se puede mezclar fácilmente con herramientas que no sean Java Unix, excepto iniciando dichas herramientas desde JVM.

Todas las máquinas virtuales con un sistema de tipo rico como Java o CLR no serán instantáneas en comparación con sistemas menos ricos como los que se encuentran en C o C ++. Esto se debe principalmente a que están sucediendo muchas cosas en la máquina virtual, muchas clases se inicializan y son requeridas por un sistema en ejecución. Las instantáneas de un sistema inicializado son útiles, pero aún cuesta cargar esa imagen de nuevo en la memoria, etc.

Una clase de línea simple de estilo hello world simple con un main todavía requiere mucho para cargarse e inicializarse. La verificación de la clase requiere una gran cantidad de verificación y validación de dependencias, todo lo cual cuesta tiempo y muchas instrucciones de CPU para ejecutar. Por otro lado, un programa en C no hará nada de esto e incluirá algunas instrucciones y luego invocará la función de impresora.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top