Comprensión profunda de JVM ==> área de datos de tiempo de ejecución

1. Introducción a JVM

  JVM es una 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.

  Una característica muy importante del lenguaje Java es su naturaleza multiplataforma. El uso de la máquina virtual Java es la clave para lograr esta característica. Si un lenguaje general de alto nivel se va a ejecutar en diferentes plataformas, al menos debe compilarse en diferentes códigos de objeto. 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 plataformas específicas, de modo que el compilador del lenguaje Java solo necesita generar el código de destino (código de bytes) que se ejecuta en la máquina virtual Java y puede ejecutarse en múltiples plataformas sin modificación. . Cuando la máquina virtual Java ejecuta bytecode, interpreta el bytecode como instrucciones de la máquina en una plataforma específica para su ejecución. Es por eso que Java puede "compilar una vez, ejecutar en todas partes".

Dos, modelo de gestión de memoria JVM

Memoria de montón (montón)

  Para la mayoría de las aplicaciones, Java Heap es la pieza de memoria más grande administrada por Java Virtual Machine. El almacenamiento dinámico de Java es un área de memoria compartida por todos los subprocesos y creada cuando se inicia la máquina virtual. El único propósito de esta área de memoria es almacenar instancias de objetos, donde casi todas las instancias de objetos tienen memoria asignada.

  La memoria de almacenamiento dinámico de Java también se puede subdividir en: generación joven y generación anterior. Entre ellos, la generación joven se puede dividir en el área del Edén, desde el espacio Survivor, hasta el espacio Survivor, etc.

  Si no hay memoria en el montón para completar la asignación de instancias, y el montón ya no puede expandirse, se generará una excepción OutOfMemoryError.

Área de método

  El área de método (área de método), como el montón de Java, es un área de memoria compartida por varios subprocesos y se utiliza para almacenar datos como información de clase, constantes, variables estáticas y código compilado por el compilador en tiempo real que ha cargado la máquina virtual. Aunque la especificación de la máquina virtual Java describe el área del método como una parte lógica del montón, tiene un alias llamado Non-Heap (no montón), el propósito debe distinguirse del montón de Java.

  Para los desarrolladores que están acostumbrados a desarrollar e implementar programas en la máquina virtual HotSpot, muchas personas están dispuestas a llamar al área de método "Generación permanente". En esencia, las dos no son equivalentes, simplemente porque la máquina virtual HotSpot El equipo de diseño eligió extender la colección de generación de GC al área del método, o utilizar la generación permanente para implementar el área del método.

  La especificación de la máquina virtual Java tiene restricciones muy flexibles en esta área. Además del montón de Java, que no requiere memoria contigua y puede ser fijo o extensible, también puede elegir no implementar la recolección de basura. Relativamente hablando, el comportamiento de recolección de basura es relativamente raro en esta área, pero no es que los datos ingresen al área del método ya que existe "permanentemente" como el nombre de la generación permanente. El objetivo de la recuperación de memoria en esta área es principalmente para la recuperación de grupos constantes y la descarga de tipos. En términos generales, el "logro" de recuperación de esta área es más difícil de satisfacer, especialmente el tipo de descarga, las condiciones son bastante duras, pero esta parte del área Reciclar es realmente necesario.

  De acuerdo con la Especificación de máquina virtual Java, cuando el área del método no puede cumplir con los requisitos de asignación de memoria, se generará una excepción OutOfMemoryError.

Contador de programa (Registro de contador de programa)

  El contador de programa (Program Counter Register) es un pequeño espacio de memoria, y su función puede considerarse 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 (solo el modelo conceptual, se pueden implementar varias máquinas virtuales de maneras más eficientes), el intérprete de código de bytes funciona cambiando el valor de este contador para seleccionar el siguiente que se ejecutará Las instrucciones de código de bytes, ramificación, bucle, salto, manejo de excepciones, recuperación de subprocesos y otras funciones básicas deben depender de este contador para completar.

  Dado que el subprocesamiento múltiple de la máquina virtual Java se implementa mediante el cambio de subprocesos y la asignación del tiempo de ejecución del procesador, en un momento dado, un procesador (para un procesador multinúcleo, un núcleo) solo ejecutará un subproceso Instrucciones. Por lo tanto, para restaurar 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 cada hilo no se afectan entre sí y se almacenan de forma independiente. Llamamos a este tipo de área de memoria "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 método Natvie se está ejecutando, el valor del contador está vacío.

  Esta área de memoria es la única que no especifica ningún OutOfMemoryError en la especificación de máquina virtual Java.

Pila de máquina virtual Java (pilas JVM)

  Al igual que el contador del programa, la pila de máquinas virtuales Java (pilas de máquinas virtuales Java) también es privada para el hilo, y su ciclo de vida es el mismo que el hilo. La pila de máquina virtual describe el modelo de memoria de la ejecución del método Java: cuando se ejecuta cada método, se crea un marco de pila (Stack Frame) al mismo tiempo para almacenar la tabla de variables locales, la pila de operaciones, el enlace dinámico, la salida del método y otra información. Se llama a cada método hasta que se completa la ejecución, que corresponde a un marco de pila de la pila a la pila en la pila de máquina virtual.

  La tabla de variables locales almacena varios tipos de datos básicos (boolean, byte, char, short, int, float, long, double), referencias de objeto (tipo de referencia, que no son equivalentes al objeto en sí, de acuerdo con diferentes máquinas virtuales Implementación, puede ser un puntero de referencia a la dirección inicial del objeto, también puede apuntar a un identificador que representa el objeto u otra ubicación relacionada con el objeto) y el tipo returnAddress (apuntando a la dirección de una instrucción de código de bytes).

  Entre ellos, los tipos de datos largos y dobles de 64 bits ocuparán 2 espacios variables locales (Slot), y los tipos de datos restantes solo ocuparán 1 slot. El espacio de memoria requerido por la tabla de variables locales se asigna durante la compilación. Al ingresar un método, se determina por completo cuánto espacio de variables locales debe asignar este método en el marco, y el tamaño de la tabla de variables locales no cambiará durante la ejecución del método.

  En la especificación de la máquina virtual Java, se especifican dos condiciones de excepción para esta área: si la profundidad de la pila solicitada por el subproceso es mayor que la profundidad permitida por la máquina virtual, se generará una excepción StackOverflowError. Si la pila de máquina virtual se puede expandir dinámicamente (la mayoría de las máquinas virtuales Java actuales se pueden expandir dinámicamente, pero la especificación de máquina virtual Java también permite una pila de máquina virtual de longitud fija), se lanzará cuando no se pueda aplicar suficiente memoria durante la expansión Excepción OutOfMemoryError.

Pilas de métodos nativos

  Las pilas de métodos nativos (pilas de métodos nativos) y las pilas de máquinas virtuales juegan un papel muy similar, la diferencia es que la pila de máquinas virtuales ejecuta servicios de métodos Java (es decir, código de bytes) para la máquina virtual, mientras que la pila de métodos locales es para Servicio de método nativo utilizado por la máquina virtual. El idioma, el uso y la estructura de datos de los métodos en la pila de métodos locales no son obligatorios en la especificación de la máquina virtual, por lo que la máquina virtual específica puede implementarlo libremente. Algunas máquinas virtuales (como la máquina virtual Sun HotSpot) combinan directamente la pila de métodos locales y la pila de máquinas virtuales en una sola. Al igual que la pila de máquina virtual, las excepciones StackOverflowError y OutOfMemoryError se lanzan en el área de pila de método local.

Grupo constante de tiempo de ejecución

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

  Una característica importante del grupo constante de tiempo de ejecución es su naturaleza dinámica. El lenguaje Java no requiere que las constantes se generen solo en tiempo de compilación, es decir, el contenido del grupo constante en el archivo de clase no está preestablecido para ingresar al grupo constante de tiempo de ejecución del área del método. Durante el período, las nuevas constantes también se pueden colocar en el grupo constante. Esta característica es utilizada a menudo por los desarrolladores es el método intern () de la clase String.

  Dado que el grupo constante es parte del área del método en tiempo de ejecución, está naturalmente limitado por la memoria del área del método. Cuando el grupo constante no puede solicitar memoria, se generará una excepción OutOfMemoryError.

Memoria directa

  La memoria directa no es parte del área de datos de tiempo de ejecución de la máquina virtual, ni es el área de memoria definida en la especificación de la máquina virtual Java. Sin embargo, esta parte de la memoria también se usa con frecuencia, y también puede causar OutOfMemoryError, por lo que se presenta aquí.

  En JDK1.4, la clase NIO (Nueva entrada / salida) se agregó recientemente y se introdujo un método de E / S basado en Canal y Buffer. Puede asignar directamente memoria fuera del montón utilizando la biblioteca nativa Un objeto DirectByteBuffer almacenado en el almacenamiento dinámico de Java se usa como referencia a esta memoria para evitar copiar datos de un lado a otro en el almacenamiento dinámico de Java y el almacenamiento dinámico nativo, lo que puede mejorar significativamente el rendimiento en algunos escenarios.

  La asignación directa de memoria no estará limitada por la memoria de almacenamiento dinámico de Java, sino que estará limitada por el tamaño total de la memoria de la máquina y el espacio de direccionamiento del procesador. Al configurar los parámetros de la máquina virtual, el administrador del servidor establece la información de parámetros como -Xms y -Xmx de acuerdo con la memoria real, pero a menudo ignora la memoria directa, por lo que la suma de cada área de memoria es mayor que el límite de memoria física, lo que resulta en una excepción OutOfMemoryError durante la expansión dinámica.

Supongo que te gusta

Origin www.cnblogs.com/L-Test/p/12736914.html
Recomendado
Clasificación