JVM detallada (1)

Consejos antes de ver:

Este artículo se refiere a la "Comprensión profunda de la máquina virtual Java" de Zhou Zhiming.

1. Introducción

JVM es la abreviatura de Java Virtual Machine (Java Virtual Machine). JVM es una especificación para dispositivos informáticos. Es una computadora ficticia que se realiza mediante la simulación de varias funciones de computadora en una computadora real.
Después de la introducción de la máquina virtual del lenguaje Java, no es necesario volver a compilar el lenguaje Java cuando se ejecuta en diferentes plataformas. El lenguaje Java utiliza la máquina virtual Java para proteger la información relacionada con la plataforma específica, de modo que el compilador del lenguaje Java solo necesita generar el código objeto (bytecode) que se ejecuta en la máquina virtual Java, y puede ejecutarse en múltiples plataformas sin modificaciones. .

2. Área de datos de tiempo de ejecución

La máquina virtual Java divide la memoria que administra en varias áreas de datos diferentes durante la ejecución del programa Java. La memoria administrada por la máquina virtual Java incluirá las siguientes áreas de datos en tiempo de ejecución, como se muestra en la figura siguiente.

Inserte la descripción de la imagen aquí

2.1 Contador de programas

El contador del programa es un pequeño espacio de memoria y su función puede verse como el indicador de número de línea del código de bytes ejecutado por el hilo actual. En el modelo conceptual de la máquina virtual, cuando el intérprete de bytecode funciona, selecciona la siguiente instrucción de bytecode a ejecutar cambiando el valor de este contador.Funciones básicas como rama, bucle, salto, manejo de excepciones, recuperación de hilos, etc. Necesito confiar en este contador para completar.

Dado que el subproceso múltiple de la máquina virtual Java se realiza mediante la forma en que los subprocesos alternan y asignan el tiempo de ejecución del procesador, en cualquier momento determinado, un procesador solo puede ejecutar instrucciones en un subproceso. Por lo tanto, para restaurar a la posición de ejecución correcta después del cambio de hilo, cada hilo necesita tener un contador de programa independiente. Los contadores entre los hilos no se afectan entre sí y se almacenan de forma independiente. A este tipo de área de memoria lo llamamos "hilo privado" Memoria.

Si el hilo está ejecutando un método Java, este contador registra la dirección de la instrucción de código de bytes de la máquina virtual que se está ejecutando; si el hilo está ejecutando un método nativo, este valor de contador está vacío (Indefinido). Esta área de memoria es la única área que no especifica ninguna condición de OutOfMemoryError en la especificación de la máquina virtual Java.

El hilo es privado y el espacio de memoria es pequeño.

Almacene la dirección de instrucción del código de bytes de la máquina virtual o vacía (Indefinida).

No hay ninguna excepción OutOfMemoryError.

2.2 Pila de máquinas virtuales Java

Al igual que el contador del programa, la pila de la máquina virtual Java es privada para el subproceso y su ciclo de vida es el mismo que el del subproceso. La pila de la máquina virtual describe el modelo de memoria de la ejecución del método Java: cuando se ejecuta cada método, los colegas crearán un marco de pila para almacenar información como tablas de variables locales, pilas de operaciones, enlaces dinámicos y salidas de métodos. El proceso desde que se llama a cada método hasta la finalización de la ejecución corresponde al proceso de este marco de pila desde que se empuja hasta que aparece en la pila de la máquina virtual.

La tabla de variables locales almacena los tipos de datos básicos (booleano, byte, char, short, int, float, long, double), referencia de objeto (tipo de referencia) y tipo returnAddress (apuntando a una instrucción de código byte habla a).

El hilo es privado y el ciclo de vida es el mismo que el del hilo.

Almacene la tabla de variables locales, la pila de operaciones, el enlace dinámico, la salida del método y otra información.

La profundidad de pila solicitada por el subproceso es mayor que la profundidad permitida por la máquina virtual, y se lanza una excepción StackOverflowError; si la máquina virtual se puede expandir dinámicamente, se lanzará una excepción OutOfemoryError cuando la expansión no pueda solicitar suficiente memoria.

2.3 Pila de métodos locales

El papel que desempeñan la pila de métodos nativos y la pila de máquinas virtuales es muy similar. La diferencia es que la pila de máquinas virtuales sirve a la máquina virtual para ejecutar métodos Java, y la pila de métodos locales sirve a los métodos nativos utilizados por la máquina virtual.

Almacenar métodos nativos.

Al igual que la pila de máquinas virtuales, también se lanzan las excepciones StackOverflowError y OutOfMemoryError.

2.4 montón de Java

Para la mayoría de las aplicaciones, el montón de Java es la mayor parte de la memoria administrada por la máquina virtual de Java. El montón de Java es un área de memoria compartida por todos los subprocesos y se crea cuando se inicia la máquina virtual. El único propósito de esta área de memoria es almacenar instancias de objetos, y casi todas las instancias de objetos asignan memoria aquí. Este punto se describe en la especificación de la máquina virtual Java: todas las instancias de objetos y matrices deben asignarse en el montón, pero con el desarrollo del compilador JIT y la madurez gradual de las técnicas de análisis de escape, las técnicas de optimización de asignación de pila y reemplazo escalar Hará que se produzcan algunos cambios sutiles, todos los objetos se asignan en el montón y gradualmente se vuelven menos "absolutos".

Desde la perspectiva de la recuperación de la memoria, dado que los recolectores actuales utilizan básicamente algoritmos de recopilación generacional, el montón de Java también se puede subdividir en: nueva generación y generación anterior; los más detallados incluyen el espacio Eden, el espacio From Survivor, Al espacio de Superviviente, etc. Desde la perspectiva de la asignación de memoria, el montón de Java compartido por los subprocesos se puede dividir en varios búferes de asignación de subprocesos privados (búfer de asignación local de subprocesos, TLAB).

Thread sharing, la mayor parte de la memoria.

Almacene instancias de objetos y matrices.

Si no hay memoria en el montón para completar la asignación de fuerza y ​​el montón no se puede expandir, se lanzará una excepción OutOfMemoryError.

2.5 Área de métodos

El área de método, como el montón de Java, es un área de memoria compartida por cada subproceso. Se utiliza para almacenar datos como información de clase, constantes, variables estáticas y código compilado por el compilador just-in-time que ha sido cargado por la máquina virtual. El área se describe como una parte lógica del montón, pero tiene un alias llamado Non-Heap, que debería distinguirse del montón de Java en la actualidad.

Compartir hilo

Almacena datos como información de clase, constantes, variables estáticas y código compilado por el compilador Just-In-Time que ha cargado la máquina virtual.

Cuando el área de método no puede cumplir con los requisitos de asignación de memoria, se lanzará una excepción OutOfMemoryError.

2.6 Pool de constantes en tiempo de ejecución

El grupo de constantes de tiempo de ejecución es parte del área de métodos. Además de la información de descripción de la versión de la clase, los campos, los métodos y las interfaces en el archivo de la clase, también hay un grupo constante. Se utiliza para almacenar varios literales y referencias de símbolos generados por el compilador. Esta parte del contenido se almacenará en el grupo de constantes de tiempo de ejecución del área de método después de que se cargue la clase.

Almacene varios literales y referencias de símbolos generados por el compilador.

Cuando el grupo de constantes ya no pueda solicitar memoria, se lanzará una excepción OutOfMemoryError.

2.7 Memoria directa

La memoria directa no es parte del área de datos de la máquina virtual cuando se está ejecutando, ni es un área de memoria definida en la máquina virtual Java, pero esta parte de la memoria también se usa con frecuencia y también puede causar OutOfMemoryError.

Obviamente, la asignación de memoria directa local no estará limitada por el tamaño del montón de Java, pero dado que es memoria, el ladrón definitivamente se verá afectado por la memoria total de la máquina (incluida la RAM y el área de intercambio o el archivo de paginación) y el espacio de direccionamiento del procesador. límite.

No es parte del área de datos cuando la máquina virtual está en ejecución.

La suma de cada área de memoria es mayor que el límite de memoria física, lo que genera excepciones OutOfMemoryError durante la expansión dinámica.

3. Acceso a objetos

Hay dos métodos de acceso principales: mediante identificadores y punteros directos

3.1 Utilice el acceso por manija

Si usa el método de acceso de identificador, una parte de la memoria se dividirá en el montón de Java como el grupo de identificadores. La dirección del identificador del objeto se almacena en la referencia y el identificador contiene las direcciones específicas de los datos de instancia del objeto y los datos de tipo.

Ventajas: la dirección de la manija estable se almacena en la referencia,El objeto se mueve(Mover objetos durante la recolección de basura es un comportamiento muy común)Solo cambie el puntero de datos de instancia en el identificador, Y la referencia en sí no necesita ser modificada

3.2 Usar acceso directo al puntero

Si se utiliza el método de acceso de puntero directo, el diseño del objeto del montón de Java debe considerar cómo colocar el resto relacionado de los datos del tipo de acceso La dirección del objeto se almacena directamente en la referencia.

ventaja:Más rápido, ahorrando el costo de tiempo de un posicionamiento de punteroDebido a que el acceso a objetos es muy frecuente en Java, este tipo de sobrecarga también representa un costo de ejecución muy considerable.

Supongo que te gusta

Origin blog.csdn.net/weixin_43611145/article/details/104727857
Recomendado
Clasificación