2. ¿Qué áreas están incluidas en el área de datos en tiempo de ejecución?
3. ¿Qué datos se almacenan en la pila y el montón respectivamente?
4. ¿Por qué deberíamos sustituir la generación permanente (PermGen) por el metaespacio (MetaSpace)?
5. ¿Conoce la estructura básica del espacio del montón? ¿En qué circunstancias un objeto pasará a la vieja generación?
6. ¿En qué área de la memoria se colocan los objetos grandes?
7. ¿Cuál es el proceso de creación de objetos Java?
Pregunta respuesta
1. ¿De qué partes consta JVM?
Respuesta: JVM es un ejecutablecódigo de bytes (.class) computadora virtual de archivos, que también proporciona administración de memoria, recolección de basura y otros mecanismos. Contiene las siguientes partes principales.
Subsistema de carga de clases: responsable de cargar archivos de código de bytes (.class) en la JVM.
Área de datos en tiempo de ejecución: es el área de memoria utilizada por la JVM durante la ejecución.
Motor de ejecución: responsable de interpretar o compilar el código de bytes en código de máquina para la ejecución del procesador.
Interfaz de biblioteca nativa: proporciona un conjunto de API para llamar a bibliotecas nativas escritas en el sistema operativo u otros idiomas.
2. ¿Qué áreas están incluidas en el área de datos en tiempo de ejecución?
Respuesta: El área de datos en tiempo de ejecución es el área de memoria asignada por la JVM al ejecutar un programa Java.
Contador de programa: es un pequeño espacio de memoria y es la dirección de la instrucción de código de bytes que el hilo ejecuta actualmente. Si el hilo ejecuta un método nativo, el valor de este contador no está definido.
Pila de máquina virtual Java: cada subproceso creará una pila de máquina virtual cuando se cree, que se utiliza para almacenar la tabla de variables locales, el marco de operandos, el enlace dinámico, la información de salida del método, etc. La pila de la máquina virtual Java contiene múltiples marcos de pila. El proceso desde cada método que se llama hasta la finalización de la ejecución corresponde al proceso desde que se inserta un marco de pila en la pila de la máquina virtual.
Pila de métodos nativos: es el espacio preparado por la JVM para ejecutar métodos nativos. Tiene funciones similares a la pila de máquinas virtuales Java. Es un modelo de memoria que describe el proceso de ejecución de métodos nativos.
Montón: se utiliza para almacenar casi todas las instancias y matrices de objetos, y es el área principal donde trabaja el recolector de basura.
Área de método: se utiliza para almacenar información de clases, constantes, variables estáticas, código compilado por el compilador justo a tiempo, etc. cargado por la JVM. Antes de JDK1.8, se implementaba como generación permanente. A partir de JDK1.8, la generación permanente se reemplaza por el espacio original. Metaspace utiliza memoria local en lugar de memoria de montón.
3. ¿Qué datos se almacenan en la pila y el montón respectivamente?
Respuesta: Datos almacenados en la pila (pila de máquina virtual Java):
Tabla de variables locales: se utiliza principalmente para almacenar parámetros de métodos y variables locales dentro del método. Los tipos de datos incluyen tipos de datos básicos y referencias de objetos.
Pila de operandos: se utiliza para almacenar temporalmente instrucciones de operación y resultados intermedios durante la ejecución del método.
Enlace dinámico: una referencia al grupo constante de la clase a la que pertenece el método, que se utiliza para resolver referencias de símbolos en el método.
Dirección de retorno del método: almacena la dirección de la siguiente instrucción ejecutada después de la llamada al método. Datos almacenados en el montón:
Instancia de objeto: una instancia de objeto creada mediante la nueva palabra clave en el programa, incluidas las propiedades y métodos del objeto.
Matriz: todo tipo de matrices, incluidas matrices de tipo básico y matrices de objetos.
4. ¿Por qué deberíamos sustituir la generación permanente (PermGen) por el metaespacio (MetaSpace)?
Respuesta: Reemplazar la generación permanente con metaespacio es principalmente para resolver algunos problemas y limitaciones inherentes de la generación permanente y mejorar el rendimiento y la flexibilidad de la JVM.
Mejore la flexibilidad y eficiencia de la administración de la memoria: el tamaño de la memoria de la generación permanente se establece cuando se inicia la JVM y no se puede ajustar dinámicamente. Metaspace utiliza memoria local en lugar de memoria dinámica de Java y su tamaño se puede ajustar dinámicamente según sea necesario.
Resuelva el problema de la descarga de clases y la recolección de basura: el comportamiento del GC de generación permanente es complejo e impredecible y la eficiencia del reciclaje es baja.
Proporcionar mejor rendimiento y estabilidad: el uso del metaespacio hace que la administración de la memoria JVM sea más unificada y consistente, porque el metaespacio, al igual que otras áreas de memoria, se administra mediante la memoria local. Esto simplifica las estrategias de administración de memoria y mejora el rendimiento y la estabilidad generales.
Simplifique la gestión de la memoria JVM
5. ¿Conoce la estructura básica del espacio del montón? ¿En qué circunstancias un objeto pasará a la vieja generación?
Respuesta: La estructura básica del espacio del montón se compone principalmente de la nueva generación, la antigua generación y la generación permanente. Después de JDK8, la generación permanente se reemplaza por metaespacio y utiliza memoria local para almacenamiento.
Generación cenozoica: El progreso de la nueva generación se subdivide en el área del Edén y dos áreas de supervivientes (Superviviente 0 y Superviviente 1)
Área del Edén: los objetos recién creados primero asignan memoria en el área del Edén.
Área de supervivencia (S0, S1): se utiliza para almacenar objetos que sobrevivieron a la recolección de basura de nueva generación. Después de cada GC menor, los objetos supervivientes se copiarán entre estas dos áreas.
Vieja generación: objetos que aún están vivos después de múltiples GC menores. La recolección de basura (Major GC o Full GC) se realiza con menos frecuencia en la generación anterior.
Generación permanente/metaespacio: se utiliza para almacenar metadatos de clases, incluidas definiciones de clases, constantes, variables estáticas, código compilado justo a tiempo, etc.
La situación cuando el objeto es de la generación anterior:
Se alcanza el umbral de edad: cada objeto tiene una edad cuando se asigna memoria en la nueva generación, y la edad aumentará en 1 después de cada GC menor. Cuando la edad alcanza un cierto umbral (el valor predeterminado es 15), el objeto pasará a la generación anterior.
Objeto grande: si el objeto es demasiado grande y excede el umbral establecido por la JVM, el objeto asignará espacio directamente en la generación anterior.
Espacio insuficiente en el área de Supervivientes: si el área de supervivientes no tiene suficiente espacio para acomodar todos los objetos supervivientes durante la GC menor, estos objetos serán
Determinación dinámica de la edad del objeto: si el tamaño de todos los objetos de la misma edad en el espacio Survivor excede la mitad del espacio Survivor, entonces los objetos cuya edad es mayor o igual a esta edad pueden ingresar directamente a la generación anterior.
// 动态年龄计算代码
uint ageTable::compute_tenuring_threshold(size_t survivor_capacity){//survivor_capacity是survivor空间的大小size_t desired_survivor_size =(size_t)((((double) survivor_capacity)*TargetSurvivorRatio)/100);//TargetSurvivorRatio 为50size_t total =0;
uint age =1;while(age < table_size){
total += sizes[age];//sizes数组是每个年龄段对象大小if(total > desired_survivor_size)break;
age++;}
uint result = age < MaxTenuringThreshold ? age : MaxTenuringThreshold;...}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
6. ¿En qué área de la memoria se colocan los objetos grandes?
Respuesta: Los objetos grandes (matrices y cadenas muy grandes) generalmente se asignan directamente en el área de memoria de la generación anterior.Esto es para evitar que la nueva generación realice frecuentesRecolección de basuraEn este momento, los objetos grandes se copian con frecuencia entre el área de Eden y el área de Survivor, lo que mejora la eficiencia de la recolección de basura. Configure el umbral para que objetos grandes ingresen directamente a la generación anterior:
7. ¿Cuál es el proceso de creación de objetos Java?
respuesta:
Comprobación de carga de clases
Si la clase no se ha cargado, conectado e inicializado, la JVM cargará la clase primero. Esto incluye los siguientes pasos:
Cargando: lea el archivo de clase a través del cargador de clases y cargue el código de bytes de la clase en la memoria.
Conexión: incluye tres etapas: verificación, preparación y análisis. Verifique la exactitud de los archivos de clase, prepare variables estáticas de la clase y asigne memoria, y resuelva las referencias de símbolos en referencias directas.
Inicialización: ejecuta el bloque de inicialización estática de la clase y la inicialización de variables estáticas.
asignación de memoria
JVM asigna memoria para nuevos objetos en el montón. El tamaño de la memoria asignada está determinado por la estructura del objeto, incluido el encabezado del objeto y los datos de la instancia.
La JVM tiene dos formas principales de asignar memoria:
Golpear el puntero: si la memoria del montón es regular, el puntero de asignación solo necesita moverse una distancia específica hasta el área de memoria libre.
Lista libre: si la memoria del montón es irregular, la JVM necesita mantener una lista libre y encontrar el bloque apropiado de la lista libre al asignar memoria.
inicializar a valor cero
La JVM inicializará todas las variables de instancia del objeto a sus valores predeterminados. Por ejemplo, las variables de tipo numérico se inicializarán en 0, las variables de tipo booleano en falso y las variables de tipo de referencia en nulo.
Establecer encabezado de objeto
Establezca la información del encabezado del objeto en el espacio de memoria del objeto, que incluye el código hash del objeto, la edad de generación de GC, el indicador de estado de bloqueo, el bloqueo retenido por el subproceso, la ID del subproceso sesgado, etc.
Inicialización del constructor
Llame al constructor del objeto para completar la inicialización del objeto. Esto incluye realizar operaciones de inicialización explícitas en variables de instancia, así como código en el cuerpo del constructor. Los pasos específicos son los siguientes:
Ejecute el bloque de inicialización de instancia de la clase.
Ejecute el método constructor de la clase principal de arriba a abajo de acuerdo con la jerarquía de herencia.
Inicialice variables de instancia con valores especificados explícitamente.
Ejecute la parte principal del método constructor de la clase.