Serie de recolección de basura y memoria JVM: motor de ejecución

Motor de ejecución

Descripción general del motor de ejecución

El motor de ejecución pertenece a la capa inferior de la JVM, que incluye un intérprete, un compilador justo a tiempo y un recolector de basura.

imagen-20200710080707873

El motor de ejecución es uno de los componentes centrales de la máquina virtual Java. "Máquina virtual" es un concepto relativo a "máquina física". Ambas máquinas tienen capacidades de ejecución de código. La diferencia es que el motor de ejecución de la máquina física se basa directamente en el procesador, la memoria caché, el conjunto de instrucciones y los niveles del sistema operativo. Y el motor de ejecución de la máquina virtual lo realiza el propio software, por lo que es posible personalizar la estructura del conjunto de instrucciones y el motor de ejecución sin estar restringido por condiciones físicas, y puede ejecutar aquellos formatos de conjuntos de instrucciones que no son directamente compatibles con el hardware.

La tarea principal de JVM es cargar código de bytes en él, pero el código de bytes no se puede ejecutar directamente en el sistema operativo, porque las instrucciones de código de bytes no son equivalentes a las instrucciones de la máquina local. Contiene solo algunas instrucciones de código de bytes, tablas de símbolos y otra información auxiliar reconocida por el JVM.

imagen-20200710081118053

Luego, si desea que se ejecute un programa Java, la tarea del motor de ejecución es interpretar / compilar instrucciones de código de bytes en instrucciones de máquina nativa en la plataforma correspondiente. En pocas palabras, el motor de ejecución de la JVM actúa como un traductor que traduce el lenguaje de alto nivel al lenguaje de máquina.

imagen-20200710081259276

El flujo de trabajo del motor de ejecución

  • Las instrucciones de código de bytes que el motor de ejecución necesita ejecutar durante el proceso de ejecución depende completamente del registro de la PC.
  • Siempre que se ejecuta una operación de instrucción, el registro de la PC actualizará la dirección de la siguiente instrucción que debe ejecutarse.
  • Por supuesto, durante la ejecución del método, el motor de ejecución puede ubicar con precisión la información de la instancia del objeto almacenada en el área del montón de Java a través de la referencia del objeto almacenada en la tabla de variables locales, y ubicar el objeto de destino a través del puntero de metadatos en el encabezado del objeto. Clasificar información.

imagen-20200710081627217

Desde el punto de vista de la apariencia, la entrada y la salida del motor de ejecución de todas las máquinas virtuales Java son las mismas: la entrada es un flujo binario de código byte, el proceso de procesamiento es el proceso equivalente de análisis y ejecución de código byte, y el resultado es el proceso de ejecución.

Proceso de compilación y ejecución de código Java

Antes de que la mayor parte del código del programa se convierta en el código de destino de la máquina física o el conjunto de instrucciones que la máquina virtual puede ejecutar, debe seguir los distintos pasos de la figura anterior.

  • La parte naranja al frente es el proceso de generación de archivos de código de bytes, que no tiene nada que ver con JVM
  • El azul y el verde detrás es el proceso que JVM debe considerar

imagen-20200710082141643

La compilación del código Java la realiza el compilador de código fuente de Java. El diagrama de flujo es el siguiente:

imagen-20200710082433146

La ejecución del código de bytes de Java se completa con el motor de ejecución de JVM, el diagrama de flujo se muestra a continuación

imagen-20200710083036258

Usamos una imagen general para hablar sobre el intérprete y el compilador.

imagen-20200710083656277

Que es intérprete

Cuando se inicia la máquina virtual Java, el código de bytes se interpretará línea por línea de acuerdo con las especificaciones predefinidas, y el contenido de cada archivo de código de bytes se "traducirá" a las instrucciones de la máquina local de la plataforma correspondiente para su ejecución.

¿Qué es un compilador de TI?

Compilador JIT (Just In Time Compiler): la máquina virtual compila directamente el código fuente en el lenguaje de la máquina relacionado con la plataforma de la máquina local.

Por qué Java es un lenguaje semi-compilado y semi-interpretado

En la era JDK1.e, es más preciso posicionar el lenguaje Java como "interpretación y ejecución". Más tarde, Java también desarrolló un compilador que puede generar directamente código nativo. Ahora, cuando la JVM ejecuta código Java, generalmente combina interpretación y ejecución con compilación y ejecución.

Después de traducir el código local, puede realizar una operación de caché y almacenarlo en el área de métodos

Código de máquina, instrucciones, lenguaje ensamblador

Codigo de maquina

Varias instrucciones expresadas en codificación binaria se denominan códigos de instrucción de máquina. Al principio, la gente lo usaba para escribir programas, que es lenguaje de máquina.

Aunque el lenguaje de máquina puede ser entendido y aceptado por las computadoras, es muy diferente de los lenguajes de las personas, no es fácil de entender y recordar por la gente, y programar con él es propenso a errores.

Una vez que el programa escrito con él se ingresa en la computadora, la CPU lo lee y ejecuta directamente, por lo que tiene la velocidad de ejecución más rápida en comparación con los programas escritos en otros lenguajes.

Las instrucciones de la máquina están estrechamente relacionadas con la CPU, por lo que los diferentes tipos de CPU se corresponden con las diferentes instrucciones de la máquina.

instrucción

Dado que el código de máquina es una secuencia binaria compuesta por 0 y 1, la legibilidad es realmente pobre, por lo que la gente inventó las instrucciones.

La instrucción es simplificar la secuencia específica de 0 y 1 en el código de máquina en la instrucción correspondiente (generalmente abreviada en inglés, como mov, inc, etc.), que es un poco más legible

Debido a que diferentes plataformas de hardware realizan la misma operación, el código de máquina correspondiente puede ser diferente, por lo que la misma instrucción (como mov) en diferentes plataformas de hardware puede tener diferentes códigos de máquina.

Conjunto de instrucciones

Las instrucciones admitidas por diferentes plataformas de hardware son diferentes. Por lo tanto, las instrucciones admitidas por cada plataforma se denominan conjunto de instrucciones de la plataforma correspondiente.
Tan común

  • Conjunto de instrucciones x86, correspondiente a la plataforma de arquitectura x86
  • Conjunto de instrucciones ARM, correspondiente a la plataforma de arquitectura ARM

Lenguaje ensamblador

Debido a que la legibilidad de las instrucciones aún es demasiado pobre, la gente inventó el lenguaje ensamblador.

En lenguaje ensamblador, los mnemónicos se usan para reemplazar los códigos de operación de las instrucciones de la máquina, y los símbolos de dirección (Symbo1) o etiquetas (Labe1) se usan para reemplazar las direcciones de instrucciones u operandos. En diferentes plataformas de hardware, el lenguaje ensamblador corresponde a diferentes conjuntos de instrucciones de lenguaje de máquina, que se convierten en instrucciones de máquina mediante el proceso de ensamblaje.

Dado que las computadoras solo reconocen códigos de instrucción, los programas escritos en lenguaje ensamblador también deben traducirse a códigos de instrucción de máquina antes de que la computadora pueda reconocerlos y ejecutarlos.

Lenguaje de alto nivel

Con el fin de facilitar la programación a los usuarios de computadoras, aparecieron más tarde varios lenguajes de computadora de alto nivel.

El lenguaje de alto nivel está más cerca del lenguaje humano que el lenguaje de máquina y el lenguaje ensamblador.Cuando una computadora ejecuta un programa escrito en un lenguaje de alto nivel, todavía necesita interpretar y compilar el programa en códigos de instrucción de máquina. El programa que completa este proceso se llama intérprete o compilador.

[Error de transferencia de imagen de enlace externo. El sitio de origen puede tener un mecanismo de enlace anti-sanguijuela. Se recomienda guardar la imagen y subirla directamente (img-CUQ0wbMr-1606810235780) (https: //tuchuang666.oss-cn-shenzhen. aliyuncs.com/img/image -20200710085323733.png)]

Los lenguajes de alto nivel no se traducen directamente en instrucciones de máquina, sino en lenguaje ensamblador, como C y C ++, como se menciona a continuación.

Proceso de ejecución del programa fuente C, C ++

El proceso de compilación se puede dividir en dos etapas: compilación y montaje.

Proceso de compilación: lea el programa fuente (flujo de caracteres), analice el léxico y la gramática y convierta instrucciones de lenguaje de alto nivel en código ensamblador funcionalmente equivalente

Proceso de ensamblaje: en realidad se refiere al proceso de traducir código en lenguaje ensamblador en instrucciones de la máquina de destino.

imagen-20200710085553258

Bytecode

Bytecode es un código binario (archivo) de un estado intermedio (código intermedio). Es más abstracto que el código de máquina y necesita ser traducido por un intérprete antes de que pueda convertirse en código de máquina.

Bytecode es principalmente para realizar operaciones de software específicas y entornos de software, y no tiene nada que ver con el entorno de hardware.

La implementación del bytecode se realiza a través de un compilador y una máquina virtual. El compilador compila el código fuente en código de bytes y la máquina virtual en una plataforma específica traduce el código de bytes en instrucciones que se pueden ejecutar directamente.

  • La aplicación típica de código de bytes es: código de bytes de Java

Interprete

La intención original de los diseñadores de JVM era simplemente cumplir con las características multiplataforma de los programas Java, por lo que evitaron el uso de compilación estática para generar directamente instrucciones de máquina local, lo que dio lugar a la implementación de intérpretes que usan línea por línea. interpretación de programas de ejecución de código de bytes en tiempo de ejecución.

imagen-20200710090203674

¿Por qué los archivos fuente de Java no se traducen directamente a JMV, sino a archivos de código de bytes? Probablemente porque el código traducido directamente es relativamente grande

La función real del intérprete es un "traductor" en tiempo de ejecución, que "traduce" el contenido del archivo de código de bytes a las instrucciones de la máquina local de la plataforma correspondiente para su ejecución.

Después de interpretar y ejecutar una instrucción de código de bytes, la operación de interpretación se realiza de acuerdo con la siguiente instrucción de código de bytes registrada en el registro de la PC que debe ejecutarse.

Clasificación de intérpretes

En la historia del desarrollo de Java, hay dos conjuntos de ejecutores de interpretación, a saber, el intérprete de código de bytes antiguo y el intérprete de plantilla que se usa comúnmente en la actualidad.

El intérprete de bytecode simula la ejecución de bytecode a través de código de software puro durante la ejecución, lo cual es muy ineficiente.

El intérprete de plantilla asocia cada código de bytes con una función de plantilla, y la función de plantilla genera directamente el código de máquina cuando se ejecuta el código de bytes, lo que mejora enormemente el rendimiento del intérprete.

En HotSpot VM, el intérprete se compone principalmente de un módulo de intérprete y un módulo de código.

  • Módulo de intérprete: implementa las funciones básicas del intérprete.
  • Módulo de código: utilizado para administrar las instrucciones de la máquina local generadas por HotSpot VM en tiempo de ejecución

status quo

Debido a que el intérprete es muy simple en diseño e implementación, además del lenguaje Java, existen muchos lenguajes de alto nivel que también se ejecutan en base al intérprete, como Python, Per1, Ruby, etc. Pero hoy en día, la ejecución basada en intérpretes se ha convertido en sinónimo de ineficiencia y, a menudo, algunos programadores de C / C ++ la ridiculizan.

Para resolver este problema, la plataforma JVM admite una tecnología llamada compilación justo a tiempo. El propósito de la compilación justo a tiempo es evitar que la función sea interpretada y ejecutada, pero compilar todo el cuerpo de la función en código de máquina. Cada vez que se ejecuta la función, solo se ejecuta el código de máquina compilado. Este método puede mejorar la eficiencia de ejecución.

Sin embargo, el modo de ejecución basado en el intérprete todavía hace una contribución indeleble al desarrollo del lenguaje intermedio.

Compilador JIT

Clasificación de ejecución de código Java

La primera es compilar el código fuente en un archivo de código de bytes y luego usar el intérprete para convertir el archivo de código de bytes en ejecución de código de máquina en tiempo de ejecución.

El segundo es compilar y ejecutar (compilar directamente en código máquina). Para mejorar la eficiencia de ejecución, las máquinas virtuales modernas utilizarán tecnología de compilación Just-In-Time (JIT, Just In Time) para compilar métodos en código de máquina antes de la ejecución.

HotSpot VM es una de las obras maestras de las máquinas virtuales de alto rendimiento actualmente en el mercado. Utiliza una arquitectura en la que coexisten un intérprete y un compilador justo a tiempo. Cuando la máquina virtual Java se está ejecutando, el intérprete y el compilador justo a tiempo pueden cooperar entre sí, aprender cada uno de las fortalezas del otro y tratar de elegir la forma más adecuada de sopesar el tiempo para compilar el código nativo y el tiempo para interpretar y ejecutar directamente el código.

Hoy en día, el rendimiento de ejecución de los programas Java ha renacido durante mucho tiempo y ha llegado a un punto en el que puede competir con los programas C / C ++.

Aquí viene el problema

Algunos desarrolladores se sorprenderán, dado que el compilador JIT ya está integrado en HotSpot VM, ¿por qué necesita utilizar un intérprete para "arrastrar" el rendimiento de ejecución del programa? Por ejemplo, JRockit VM no incluye un intérprete y todos los códigos de bytes son compilados y ejecutados por un compilador justo a tiempo.

  • La máquina virtual JRockit corta el intérprete, es decir, solo usa el compilador justo a tiempo. Eso es porque JRockit solo se implementa en el servidor. Generalmente, hay tiempo para que compile las instrucciones. La respuesta no es exigente. Una vez que se completa la compilación del compilador oportuno, proporcionará un mejor rendimiento.

Antes que nada, aclara:
cuando se inicia el programa, el intérprete puede entrar en vigor inmediatamente, ahorrando el tiempo de compilación y ejecutándolo de inmediato.
Para que el compilador funcione, se necesita una cierta cantidad de tiempo de ejecución para compilar el código en código local. Pero después de compilar en código nativo, la eficiencia de ejecución es alta.

Por lo tanto:
aunque el rendimiento de ejecución del programa en la máquina virtual JRockit será muy eficiente, inevitablemente tomará más tiempo compilar cuando se inicie el programa. Para las aplicaciones del lado del servidor, el tiempo de inicio no es el centro de atención, pero para aquellos escenarios de aplicación que valoran el tiempo de inicio, puede ser necesario adoptar una arquitectura en la que un intérprete y un compilador justo a tiempo coexistan a cambio de un equilibrio. .

En este modo, cuando se inicia el virtualizador de Java, el intérprete puede desempeñar un papel primero, en lugar de esperar a que el compilador justo a tiempo complete la compilación antes de ejecutar, lo que puede ahorrar mucho tiempo de compilación innecesario. A medida que pasa el tiempo, el compilador entra en juego, compilando más y más códigos en códigos locales y ganando una mayor eficiencia de ejecución.

Al mismo tiempo, la interpretación y la ejecución sirven como la "puerta de escape" del compilador cuando falla la optimización radical del compilador.

Método de ejecución HotSpot JVM

Cuando se inicia la máquina virtual, el intérprete puede trabajar primero, en lugar de esperar a que el compilador justo a tiempo complete la compilación y luego la ejecute, lo que puede ahorrar mucho tiempo de compilación innecesario. Y con el paso del tiempo de ejecución del programa, el compilador justo a tiempo entra en juego gradualmente, de acuerdo con la función de detección de puntos calientes, el valioso código de bytes se compila en las instrucciones de la máquina local a cambio de una mayor eficiencia de ejecución del programa.

Caso de estudio

Preste atención a la sutil relación dialéctica entre interpretación y ejecución y compilación y ejecución en el entorno en línea. La carga que la máquina puede soportar en estado cálido es mayor que en estado frío. Si el flujo se corta con el tráfico en estado cálido, el servidor en estado frío puede suspenderse debido a que no puede transportar el tráfico.

En el proceso de liberación del entorno de producción, la liberación se lleva a cabo en lotes, divididos en varios lotes de acuerdo con la cantidad de máquinas, y la cantidad de máquinas en cada lote representa como máximo 1/8 de todo el clúster. Ha habido un caso de falla como este: un programador lanzado en lotes en la plataforma de lanzamiento, y al ingresar el número total de lotes de lanzamiento, completó por error los ingredientes como dos lanzamientos. Si está en el estado caliente, en circunstancias normales, la mitad de las máquinas apenas pueden transportar tráfico, pero debido a que la JVM recién iniciada se interpreta y ejecuta, las estadísticas de código activo y la compilación dinámica JIT no se han realizado, lo que da como resultado el 1 / actual 2 después de que se inicia la máquina. Todos los servidores cayeron inmediatamente. Esta falla indica la existencia de JIT. —Equipo Ali

imagen-20200710095417462

Explicación del concepto

  • El "período de compilación" del lenguaje Java es en realidad un período de operación "incierta", porque puede referirse a un compilador de front-end (en realidad llamado "compiler front-end" es más preciso) que convierte archivos .java en archivos .class Proceso; también puede hacer referencia al compilador de tiempo de ejecución de back-end de la máquina virtual (compilador JIT, compilador Just In Time)
  • El proceso de convertir código de bytes en código de máquina.
  • También puede referirse al proceso de usar un compilador estático anticipado (compilador anticipado) para compilar directamente archivos .java en el código de la máquina local.

Compilador front-end: Javac de Sun, compilador incremental (ECJ) en Eclipse JDT.

Compilador JIT: compilador C1 y C2 de HotSpot VM.

Compilador AOT: compilador GNU para Java (GCJ), Excelsior JET.

Tecnología de detección de puntos calientes

Un método que se llama varias veces, o un cuerpo de bucle con una gran cantidad de bucles en el cuerpo del método, se puede llamar "código activo", por lo que el compilador JIT puede compilarlo en instrucciones de máquina local. Dado que este método de compilación ocurre durante la ejecución del método, se denomina reemplazo en la pila o compilación OSR (Reemplazo en la pila) para abreviar.

¿Cuántas veces es necesario llamar a un método o cuántas veces debe ejecutarse un cuerpo de bucle para alcanzar este estándar? Debe requerirse un umbral claro antes de que el compilador JIT compile este "código activo" en las instrucciones de la máquina local para su ejecución. Aquí depende principalmente de la función de detección de puntos calientes.

El método de detección de puntos calientes utilizado actualmente por HotSpot VM es la detección de puntos calientes basada en contadores.

Usando la detección de puntos calientes basada en contadores, HotSpot V creará dos tipos diferentes de contadores para cada método, a saber, el Contador de invocación y el Contador de borde posterior.

  • El contador de llamadas a métodos se utiliza para contar el número de llamadas a métodos
  • El contador de retorno de borde se usa para contar el número de bucles ejecutados por el cuerpo del bucle

Contador de llamadas de método

Este contador se utiliza para contar el número de veces que se llama al método. Su umbral predeterminado es 1500 veces en el modo Cliente y 10000 veces en el modo Servidor. Si se supera este umbral, se activará la compilación JIT.

Este umbral se puede configurar manualmente a través del parámetro de máquina virtual -XX: CompileThreshold.

Cuando se llama a un método, primero verificará si el método tiene una versión compilada con JIT, si existe, se usará primero el código nativo compilado. Si no hay una versión compilada, agregue 1 al valor del contador de llamadas al método y luego determine si la suma del contador de llamadas al método y el valor del contador de retorno excede el umbral del contador de llamadas al método. Si se ha superado el umbral, se enviará una solicitud de compilación de código para este método al compilador Just-In-Time.

imagen-20200710101829934

Atenuación de puntos calientes

Si no se establece nada, el contador de llamadas al método no cuenta el número absoluto de llamadas al método, sino una frecuencia de ejecución relativa, es decir, el número de llamadas al método dentro de un período de tiempo. Cuando se excede un cierto límite de tiempo, si el número de llamadas al método aún no es suficiente para enviarlo al compilador Just-In-Time para su compilación, el contador de llamadas de este método se reducirá a la mitad. Este proceso se llama el contador de caída del contador de llamadas al método., Y este período de tiempo se denomina tiempo de vida media del contador (tiempo de vida media del contador)

  • El ciclo de vida medio es un concepto en química. Por ejemplo, la edad de las reliquias culturales desenterradas se puede obtener marcando C60.

La acción de la descomposición del calor se realiza por cierto cuando la máquina virtual está recolectando basura. Puede usar el parámetro de máquina virtual
-XX: -UseCounterDecay para apagar la descomposición del calor y dejar que el método cuente el número absoluto de llamadas al método. De esta manera, siempre que el sistema se ejecute durante el tiempo suficiente, la mayoría de los métodos se compilarán en código local.

Además, puede utilizar el parámetro -XX: CounterHalfLifeTime para establecer el tiempo del ciclo de vida media, en segundos.

Contador de atrás a borde

Su función es contar el número de ejecuciones del código del cuerpo del bucle en un método, y la instrucción de que el flujo de control salta hacia atrás en el código de bytes se denomina "borde posterior". Obviamente, el propósito de establecer estadísticas de contador de reverso es activar la compilación de OSR.

imagen-20200710103103869

HotSpotVM puede configurar el método de ejecución del programa

De forma predeterminada, HotSpot VM adopta una arquitectura en la que coexisten un intérprete y un compilador justo a tiempo. Por supuesto, los desarrolladores pueden especificar explícitamente para la máquina virtual Java a través de comandos de acuerdo con escenarios de aplicación específicos si usar el intérprete en tiempo de ejecución o no. Se ejecuta en su totalidad con un compilador justo a tiempo. Como sigue:

  • -Xint: ejecuta el programa completamente en modo intérprete;
  • -Xcomp: el programa se ejecuta en modo de compilador justo a tiempo completo. Si hay un problema con la compilación justo a tiempo, el intérprete intervendrá en la ejecución.
  • -Xmixed: Adopte un modo mixto de intérprete + compilador just-in-time para ejecutar programas juntos.

imagen-20200710103340273

Clasificación JIT en HotSpotVM

Los compiladores JIT también se dividen en dos tipos, a saber, C1 y C2. Hay dos compiladores JIT integrados en HotSpot VM, a saber, Client Compiler y Server Compiler, pero en la mayoría de los casos, los llamamos compilador C1 y C2 para abreviar. Los desarrolladores pueden especificar explícitamente qué tipo de compilador justo a tiempo utiliza la máquina virtual Java en tiempo de ejecución mediante el siguiente comando, como se muestra a continuación:

  • -cliente: especifique la máquina virtual Java que se ejecutará en modo Cliente y utilizará el compilador C1;

    • El compilador C1 realizará optimizaciones simples y confiables en el código de bytes, lo que lleva poco tiempo. Para lograr una velocidad de compilación más rápida.
  • -server: especifique la máquina virtual Java para que se ejecute en modo servidor y utilice el compilador C2.

    • C2 realiza optimizaciones que requieren mucho tiempo y optimizaciones radicales. Pero la ejecución de código optimizada es más eficiente. (Usando C ++)

Diferentes estrategias de optimización para compiladores C1 y C2

Existen diferentes estrategias de optimización en diferentes compiladores En el compilador C1, hay principalmente métodos para inlining, des-virtualización y eliminación de excedentes.

  • Inlinación de métodos: compile el código de función referenciado en el punto de referencia, lo que puede reducir la generación de marcos de pila, reducir el paso de parámetros y los procesos de salto
  • Desvirtualización: en línea el único ventilador de implementación
  • Eliminación de redundancia: despliegue algún código que no se ejecutará durante la operación

La optimización de C2 es principalmente a nivel global, y el análisis de escape es la base de la optimización. Hay varias optimizaciones en C2 basadas en análisis de escape:

  • Reemplazo escalar: reemplace el valor de atributo del objeto agregado con un valor escalar
  • Asignación en la pila: para los objetos que no se han escapado, los objetos se asignan en la pila en lugar del montón
  • Eliminación de sincronización: operación de sincronización clara, generalmente denominada sincronizada

Estrategia de compilación estratificada

Estrategia de compilación por niveles (compilación por niveles): la interpretación y ejecución del programa (sin la supervisión del rendimiento habilitada) puede activar la compilación C1 y compilar el código de bytes en el código de máquina. Se puede realizar una optimización simple o se puede agregar la supervisión del rendimiento. La compilación C2 se basará en el rendimiento seguimiento La información se optimiza radicalmente.

Sin embargo, después de la versión Java7, una vez que el desarrollador especifica explícitamente el comando "-server" en el programa, la estrategia de compilación jerárquica se activará de forma predeterminada y el compilador C1 y el compilador C2 cooperarán entre sí para realizar las tareas de compilación.

para resumir

  • En términos generales, el rendimiento del código de máquina compilado por JIT es mejor que el de un intérprete.
  • El tiempo de inicio del compilador C2 es más lento que el del C1. Una vez que el sistema se ejecuta de manera estable, la velocidad de ejecución del compilador C2 es mucho más rápida que la del compilador C1.

Compilador AOT

jdk9 introdujo el compilador AoT (compilador estático adelantado, compilador Ahead of Time)

Java 9 introdujo la herramienta de compilación experimental AOT aotc. Utiliza el compilador Graal para convertir los archivos de clase Java de entrada en código de máquina y almacenarlos en la biblioteca compartida dinámica generada.

La denominada compilación AOT es un concepto opuesto a la compilación justo a tiempo. Sabemos que la compilación justo a tiempo se refiere al proceso de convertir el código de bytes en código de máquina que se puede ejecutar directamente en el hardware durante la ejecución del programa e implementarlo en el entorno de alojamiento. La compilación AOT se refiere al proceso de convertir el código de bytes en código de máquina antes de que se ejecute el programa.

.java -> .class -> (使用jaotc) -> .so

El mayor beneficio: la carga de la máquina virtual Java se ha compilado previamente en una biblioteca binaria y se puede ejecutar directamente. No es necesario esperar a que el compilador se caliente a tiempo, lo que reduce la mala experiencia de "primera ejecución lenta" para las aplicaciones Java.

Desventajas:

  • Destruya el java "compilar una vez, ejecutar en todas partes", debe compilar el paquete de lanzamiento correspondiente para cada hardware y sistema operativo diferentes
  • La naturaleza dinámica del proceso de vinculación de Java se reduce, y el compilador debe conocer todo el código cargado.
  • Todavía es necesario continuar optimizando, inicialmente solo es compatible con Linux X64 base java

Escribe hasta el final

  • Desde JDK10, HotSpot ha agregado un nuevo compilador justo a tiempo: compilador Graal
  • Efecto de compilación El compilador G2 se ha revisado en solo unos años, y se puede esperar el futuro
  • Actualmente, con la etiqueta de estado del experimento, debe usar el parámetro de cambio para activarlo antes de poder usarlo
-XX:+UnlockExperimentalvMOptions -XX:+UseJVMCICompiler

Supongo que te gusta

Origin blog.csdn.net/weixin_43314519/article/details/110437956
Recomendado
Clasificación