Este artículo explica principalmente su principio de funcionamiento en detalle mediante el análisis de la pila, el montón y el grupo constante de asignación de memoria de Java.
1. Prototipo de memoria de máquina virtual Java
Registro: no tenemos control sobre el programa. Pila: almacena tipos básicos de datos y referencias de objetos, pero el objeto en sí no se almacena en la pila, sino que se almacena en el montón: almacena los datos generados con un dominio estático. : se almacena en el grupo de constantes de miembros estáticos definido con estático: almacena constantes. Almacenamiento no RAM: espacio de almacenamiento permanente, como el disco duro.
2. Piscina constante
El grupo constante se refiere al grupo constante que se determina en el momento de la compilación y se guarda en la memoria compilada. Algunos datos en el archivo de clase. Además de los valores constantes (final) que contienen varios tipos básicos (como int, long, etc.) y tipos de objetos (como String y matrices) definidos en el código, también contiene algunas referencias simbólicas en forma de texto. , como:
1. Nombres completos de clases e interfaces;
2. Nombre del campo y descriptor;
3. Métodos, nombres y descriptores.
La máquina virtual debe mantener un grupo constante para cada tipo cargado. El grupo de constantes es un conjunto ordenado de constantes utilizadas por este tipo, incluidas constantes directas (constantes de cadena, enteras y de punto flotante) y referencias simbólicas a otros tipos, campos y métodos. Para las constantes de cadena, sus valores están en el grupo de constantes. El grupo de constantes en la JVM existe en forma de tabla en la memoria. Para el tipo String, hay una tabla CONSTANT_String_info de longitud fija que se utiliza para almacenar valores de cadena literales. Nota: Esta tabla solo almacena valores de cadena literales, no símbolos. . Dicho esto, debe tener una comprensión clara de la ubicación de almacenamiento de los valores de cadena en el grupo constante. Cuando se ejecuta el programa, el grupo constante se almacenará en el Área de método en lugar del montón.
3. Apilar en la asignación de memoria de Java
La unidad básica de la pila es el marco (o marco de pila): cada vez que se ejecuta un subproceso Java, la máquina virtual Java asigna una pila Java al subproceso. Cuando el hilo ejecuta un determinado método Java, inserta un marco en la pila de Java. Este marco se utiliza para almacenar parámetros, variables locales, operandos, resultados de operaciones intermedias, etc. Cuando este método complete la ejecución, el marco se extraerá de la pila. Todos los datos de la pila de Java son privados y ningún otro subproceso puede acceder a los datos de la pila del subproceso. Algunos tipos básicos de datos variables y variables de referencia de objetos definidas en la función se asignan en la memoria de pila de la función. Cuando una variable se define en un bloque de código, Java asigna espacio de memoria para la variable en la pila. Cuando la variable sale del alcance, Java liberará automáticamente el espacio de memoria asignado para la variable y el espacio de memoria se podrá utilizar inmediatamente. ser utilizado para otros fines.
4. Montón en la asignación de memoria de Java
El montón en la máquina virtual Java se utiliza para almacenar objetos y matrices creados por nuevos. La memoria asignada en el montón es administrada por el mecanismo automático de recolección de basura de la máquina virtual Java. En pocas palabras, en comparación con la pila, el montón se usa principalmente para almacenar objetos Java, y la pila se usa principalmente para almacenar referencias de objetos... Después de generar una matriz u objeto en el montón, también se puede generar una variable especial. definido en la pila, de modo que El valor de esta variable en la pila es igual a la primera dirección de la matriz u objeto en la memoria del montón. Esta variable en la pila se convierte en la variable de referencia de la matriz u objeto. Una variable de referencia equivale a darle un nombre a una matriz u objeto. Luego puede usar la variable de referencia en la pila para acceder a la matriz u objeto en el montón del programa. Una variable de referencia equivale a darle un nombre a una matriz u objeto.
Las variables de referencia son variables ordinarias que se asignan en la pila cuando se definen. Las variables de referencia se liberan después de que el programa se ejecuta fuera de su alcance. Las matrices y los objetos en sí se asignan en el montón. Incluso si el programa se ejecuta fuera del bloque de código donde se encuentra la declaración que usa new para generar la matriz u objeto, la memoria ocupada por la matriz y el objeto en sí no se liberará. Los objetos no tienen variables de referencia que apunten a ellos, se convierte en basura y ya no se puede usar, pero aún ocupa el espacio de memoria y será recolectado (liberado) por el recolector de basura en un momento indeterminado posterior. Ésta es también la razón por la que Java ocupa más memoria. De hecho, las variables en la pila apuntan a variables en la memoria del montón. ¡Esto es un puntero en Java!
El montón de Java es un área de datos en tiempo de ejecución desde la cual los objetos de clase asignan espacio. Estos objetos se crean mediante instrucciones como new, newaray, anewarray y multianewarray, y no requieren que el código del programa se libere explícitamente. El montón se recopila mediante recolección de basura. Responsable, la ventaja del montón es que puede asignar dinámicamente el tamaño de la memoria y no es necesario informarle al compilador la vida útil con anticipación, porque asigna memoria dinámicamente en tiempo de ejecución y el recolector de basura de Java recolectará automáticamente los que ya no se usan. datos, pero la desventaja es que debido a la necesidad de asignar memoria dinámicamente en tiempo de ejecución, la velocidad de acceso es lenta.
La ventaja de la pila es que la velocidad de acceso es más rápida que la del montón, solo superada por el registro, y los datos de la pila se pueden compartir. Pero la desventaja es que se debe determinar el tamaño y la vida útil de los datos almacenados en la pila y hay una falta de flexibilidad. La pila almacena principalmente algunos tipos básicos de datos variables (int, short, long, byte, float, double, boolean, char) y identificadores de objetos (referencias).
Una característica especial muy importante de la pila es que los datos almacenados en la pila se pueden compartir. Supongamos que también definimos:
int a=3; int b=3; el compilador primero procesa int a = 3; primero crea una referencia a la variable a en la pila y luego verifica si hay un valor de 3 en la pila. configurará 3 Almacénelo y luego apunte a 3. Luego procese int b = 3 después de crear la variable de referencia de b, debido a que ya hay un valor de 3 en la pila, b apuntará directamente a 3; De esta forma aparecen a y b al mismo tiempo, ambos apuntan al caso de 3.
En este momento, si a = 4 se establece nuevamente, el compilador volverá a buscar si hay un valor 4 en la pila. Si no, almacenará 4 y señalará 4, si ya existe. apuntará directamente a esta dirección. Por lo tanto, los cambios en el valor de a no afectarán el valor de b.
Cabe señalar que este tipo de intercambio de datos es diferente del intercambio de referencias de dos objetos que apuntan a un objeto al mismo tiempo, porque en este caso la modificación de a no afectará a b, la completa el compilador, que Es beneficioso para ahorrar espacio. Si una variable de referencia de objeto modifica el estado interno del objeto, afectará a otra variable de referencia de objeto.