Detalles de Java JVM:
Conocimiento relacionado sobre JVM
1. Memoria de montón y pila
1. La memoria de la pila en JVM almacena principalmente referencias a tipos básicos de variables y objetos.
2. La memoria del montón en JVM almacena principalmente objetos y matrices creadas con cadenas nuevas y de longitud variable (StringBuilder y StringBuffered) se almacenan en la memoria de Heap.
La ventaja de usar el montón es que es un espacio de almacenamiento asignado dinámicamente, lo cual es más flexible, pero la desventaja es que es más lento asignar la memoria dinámicamente; Si bien el uso de la pila es más rápido, y el intercambio de datos se puede lograr, pero la desventaja es que el tamaño de los datos y la vida útil en la pila deben determinarse y carecer de flexibilidad
3. La asignación de almacenamiento estático se utiliza para almacenar variables estáticas y bloques de código estático.
2. Comprensión de JVM
JVM es una máquina virtual Java. Bloquea información relacionada con la plataforma del sistema operativo específico, de modo que el programa Java solo genera código de objeto (código de byte) que se ejecuta en la máquina virtual Java, de modo que se pueda lograr la operación multiplataforma;
Su principio es: el archivo de origen Java se compila en programas ByTecode a través del compilador Java, y cada instrucción se traduce en código de máquina de diferentes plataformas a través de JVM, y se ejecuta a través de una plataforma específica;
El área de memoria de JVM se divide principalmente en: área de método, pila JVM, montón, pila de métodos locales, contador de programa
Contador del programa: se usa para registrar la instrucción actualmente ejecutada, que es el único área sin OOM;
JVM Stack: el hilo es privado. Cada hilo creará una pila JVM al mismo tiempo. Almacena variables básicas locales en el hilo actual, resultados de retorno parcial, marco de pila y dirección de referencia de objetos;
Heap: intercambio de hilos, utilizado para almacenar algunos objetos y matrices; Dado que se comparte, se requieren bloqueos, lo que conduce a una alta sobrecarga;
Área de método: este área de método corresponde a una generación persistente, que almacena la información de la clase (nombre, modificador, etc.), variables estáticas en la clase, constantes definidas en la clase con final, etc.;
Pila de métodos locales: se utiliza para admitir la ejecución de métodos nativos y almacenar el estado de la llamada de cada método nativo;
La recolección de basura de Java se centra principalmente en las áreas del montón y el método: el montón se divide en la nueva generación y la antigua generación, y generalmente los objetos que acaban de ser nuevos se colocarán en la nueva generación; y la nueva generación se divide en el área del Edén y dos áreas de sobrevivientes;
El mecanismo de la recolección de basura es: primero determinar qué objetos son basura, es decir, ya no se usan, y luego usan los algoritmos correspondientes (algoritmo de limpieza de marcas, algoritmo de copia, algoritmo de marca, algoritmo generacional de recolección) para recolectar la basura;
1. Algoritmo de limpieza de marcas:
Se divide en dos etapas, la etapa de marcado y la etapa de limpieza. Primero, marque el objeto que necesita ser reciclado y luego reciclar el espacio ocupado por el objeto de marcado;
Su implementación es relativamente simple, pero su desventaja es que es fácil generar fragmentos de memoria, lo que resulta en la incapacidad de encontrar suficiente memoria al asignar espacio para objetos grandes en el futuro y provocar una nueva acción de recolección de basura por adelantado;
2. Algoritmo de copia:
Para resolver las deficiencias del algoritmo de limpieza de marcas, el algoritmo de copia divide la memoria en dos áreas de igual tamaño según la capacidad, y solo uno de ellos se usa a la vez. Después de que se usa una pieza, el objeto aún ascendente se copia a otra área, y luego se limpia el área usada, por lo que la fragmentación no es fácil de ocurrir;
El problema de la fragmentación de la memoria se resuelve, pero la desventaja es que la memoria utilizada se reduce a la mitad del original, y la eficiencia de copia está relacionada con el número de objetos sobrevivientes. Cuando el número es grande, la eficiencia se reduce considerablemente;
3. Algoritmo de organización de marcado
Para resolver los defectos del algoritmo de copia, nació el algoritmo Mark-Tidy, y la etapa de marcado también era como el algoritmo de limpieza de marcas. Primero, los objetos que deben reciclar están marcados, pero no los recicla directamente, sino que mueve todos los objetos sobrevivientes al otro lado, y luego limpia la memoria fuera del límite;
4. Algoritmo de colección generacional
Este es el algoritmo más utilizado en la actualidad. Su idea central es dividir la memoria en varias áreas diferentes de acuerdo con el ciclo de supervivencia del objeto. En general, el área del montón se divide en la nueva generación y la antigua generación. La característica de la antigua generación es que hay menos objetos que deben reciclar cada vez que se recolecta la basura, mientras que hay más de la nueva generación, por lo que se adoptan algoritmos diferentes;
En la actualidad, la mayoría de la nueva generación usa algoritmos de copia, pero de hecho, la nueva generación no se divide en una relación 1: 1. En términos generales, la nueva generación se divide en un espacio de Edén más grande y dos espacios de sobrevivientes más pequeños. Cada vez que se usan el espacio Eden y uno de los espacios de sobrevivientes, cuando se recicla, los objetos aún ascendentes en Edén y Survivor se copian a otro espacio de sobrevivientes, y luego se limpian Eden y los espacios de sobrevivientes que se acaban de usar.
Debido a que la vejez es que solo un pequeño número de objetos se reciclan cada vez, el algoritmo de marca compacto generalmente se usa.
Tenga en cuenta que hay otra generación fuera del área del montón, que es la generación permanente, que se utiliza para almacenar clases de clases, constantes, descripciones de métodos, etc. El reciclaje de la generación permanente recicla principalmente dos partes: constantes descartadas y clases inútiles.
Entonces, ¿cómo determinamos qué objeto es "basura"?
Método 1. Método de conteo de referencia:
En Java, se asocia con objetos a través de referencias, es decir, si desea operar objetos, debe hacerse a través de referencias. Entonces es obvio que una manera fácil es juzgar si un objeto se puede reciclar mediante el conteo de referencia. Sin perder la generalidad, si un objeto no tiene referencias asociadas con él, significa que es básicamente poco probable que el objeto se use en otro lugar, y luego el objeto se convierte en un objeto reciclable. Este método se convierte en el método de conteo de referencia.
Ventajas: implementación simple y alta eficiencia
Desventajas: no puede resolver el problema de las referencias circulares
Método 2. Método de análisis de accesibilidad:
La idea básica de este método es buscar a través de una serie de objetos "Roots GC" como punto de partida. Si no hay una ruta accesible entre "Roots GC" y un objeto, se dice que el objeto es inalcanzable. Sin embargo, debe tenerse en cuenta que el objeto juzgado como inalcanzable puede no convertirse necesariamente en un objeto reciclable. Un objeto que se juzga como inalcanzable debe pasar por al menos dos procesos de marcado para convertirse en un objeto reciclable. Si todavía no hay posibilidad de convertirse en un objeto reciclable durante estos dos procesos de marcado, básicamente se convertirá en un objeto reciclable.
¿Qué objetos pueden ser Roots GC?
1. Objeto referenciado en la pila JVM (tabla de variables locales en el marco de la pila).
2. Objeto referenciado por los atributos estáticos de clase en el área del método.
3. Objetos a los que se hace referencia por constantes en el área del método
4. Objeto referenciado por JNI (es decir, el método nativo general) en la pila del método local.
Para los programadores, también podemos reducir la sobrecarga de GC a través de algunos métodos:
1. No muestre el método System.gc ()
2. Minimizar el uso de objetos temporales
3. Cuando el objeto no está en uso, la configuración de visualización está configurada en NULL
4. Intenta usar StringBuilder en lugar de cadenas acumuladas
5. Si puede usar tipos básicos de variables (int long), no use objetos (entero, largo)
6. Use variables de objetos estáticos lo menos posible
Gracias por leer, espero que pueda ayudarte. ¡Gracias por su apoyo para este sitio!