[Java] JVM (5)

mecanismo de recogida de basura

Juzgar la supervivencia del objeto.

Casi todas las instancias de objetos se almacenan en el montón. Antes de que el recolector de basura recicle los objetos, lo que hay que hacer es determinar cuáles de estos objetos siguen "sobreviviendo" y cuáles están "muertos" (muertos significa que es imposible reutilizarlos). ) Cualquier forma de usar el objeto)

análisis de accesibilidad

Para determinar si el objeto está vivo o no. La idea básica de este algoritmo es utilizar una serie de GC Rootsobjetos llamados " " como punto de partida. Partiendo de estos nodos 向下搜索, el camino recorrido por la búsqueda se llama 引用链(Cadena de referencia). Cuando un objeto está conectado a GC Roots sin cualquier cadena de referencia, prueba que el objeto no está disponible.

Los objetos que sirven como raíces de GC incluyen los siguientes (enfóquese en los primeros cuatro):

虚拟机栈(栈帧中的本地变量表)中引用的对象;Parámetros, variables locales, variables temporales, etc. utilizados en cada pila de métodos de llamada de subprocesos.

方法区中类静态属性引用的对象;Una variable estática de tipo de referencia de una clase java.

方法区中常量引用的对象; Por ejemplo: referencias en el grupo de constantes de cadena.

本地方法栈中JNI(即一般说的Native方法)引用的对象

Referencias internas de JVM (objeto de clase, objeto de excepción NullPointException, OutofMemoryError, cargador de clases del sistema). (sin énfasis)

 Todos los objetos retenidos por bloqueos de sincronización (clave sincronizada). (sin énfasis)

JMXBean dentro de JVM, devoluciones de llamadas registradas en JVMTI, caché de código local, etc. (sin énfasis)

 Objetos "temporales" en la implementación de JVM, objetos a los que se hace referencia entre generaciones (al usar el modelo generacional para reciclar objetos que solo reciclan una parte de la generación, esto se explicará en detalle más adelante, obtengamos una comprensión general del concepto primero) ( sin énfasis)

El reciclaje anterior es todos los objetos, y las condiciones de reciclaje de la clase son las siguientes:

Tenga en cuenta que para que Class se recicle, las condiciones son relativamente duras y se deben cumplir las siguientes condiciones al mismo tiempo (solo es posible, no necesariamente, porque todavía hay algunos parámetros que se pueden controlar):

1. Todas las instancias de esta clase se han reciclado, es decir, no hay instancias de esta clase en el montón.

2. El ClassLoader que carga esta clase ha sido reciclado.

3. No se hace referencia al objeto java.lang.Class correspondiente a esta clase en ninguna parte, y no se puede acceder al método de esta clase a través de la reflexión en ninguna parte.

Finalizar método

Incluso si el objeto inalcanzable se juzga a través del análisis de accesibilidad, no es "debe morir", todavía estará en la etapa de "prueba". Para realmente declarar un objeto muerto, debe pasar por dos procesos de marcado, uno no se encuentra con GCRoots Reference chain, que se marcará por primera vez. Luego realice una proyección (si el objeto anula finalizar), podemos guardarlo en finalizar.

cita

fuerte referencia

General Object obj = new Object() es una referencia fuerte. En cualquier caso, siempre que haya una asociación de referencia sólida (accesible a la raíz), el recolector de elementos no utilizados nunca reclamará el objeto al que se hace referencia.

Referencia suave Referencia suave

Algunos objetos útiles pero no necesarios asociados con referencias blandas se reciclarán antes de que el sistema desborde la memoria (OuyOfMemory) (si aún no hay suficiente espacio después de este reciclaje, se producirá un desbordamiento de memoria).

Por ejemplo, se utiliza un programa para procesar imágenes proporcionadas por los usuarios. Si todas las imágenes se leen en la memoria, aunque las imágenes se pueden abrir rápidamente, el espacio de la memoria será enorme y algunas imágenes menos utilizadas desperdiciarán espacio en la memoria y deberán eliminarse manualmente de la memoria. Si cada vez que se abre una imagen, se lee desde el archivo del disco a la memoria y luego se muestra. Aunque el uso de la memoria es pequeño, algunas imágenes de uso frecuente necesitan acceder al disco cada vez que se abren, y el costo es enorme. En este momento, puede usar referencias suaves para crear cachés.

Referencia débil Referencia débil

Algunas son útiles (más bajas que las referencias blandas), pero no necesarias. Los objetos asociados con referencias débiles solo pueden sobrevivir hasta la próxima recolección de elementos no utilizados. Cuando se produce la recopilación de basura, independientemente de si hay suficiente memoria, se reciclará.

Nota: Las referencias suaves SoftReference y las referencias débiles WeakReference se pueden usar en el caso de recursos de memoria limitados y la creación de cachés de datos que no son muy importantes. Cuando la memoria del sistema es insuficiente, se puede liberar el contenido de la memoria caché.

Aplicación práctica (WeakHashMap, ThreadLocal)

Referencia virtual PhantomReference

Referencia fantasma, la más débil (será reciclada en cualquier momento)

Se recibe una notificación durante la recolección de elementos no utilizados para monitorear si el recolector de elementos no utilizados funciona correctamente.

También existe una aplicación típica en JDK: DirectByteBuffer.
DirectByteBuffer, que tiene las características de copia cero, es utilizado por varios marcos NIO como Netty y utilizará memoria fuera del montón. La propia JVM administra la memoria del montón, y la memoria fuera del montón debe liberarse manualmente. DirectByteBuffer no tiene un finalizador. Su trabajo de limpieza de la memoria nativa se completa automáticamente con sun.misc.Cleaner, que es una herramienta de limpieza basada en PhantomReference, que es mejor que los finalizadores ordinarios.

Estrategia de asignación de objetos

Los objetos grandes van directamente a la vieja generación

Un objeto grande se refiere a un objeto Java que requiere una gran cantidad de espacio de memoria continuo. El objeto grande más típico es una cadena muy larga o una matriz con una gran cantidad de elementos.

Un objeto grande es una mala noticia para la asignación de memoria de una máquina virtual. La peor noticia que encontrar un objeto grande es encontrar un grupo de "objetos grandes de corta duración" que "viven y mueren", escribimos. evitar esto al programar.

La razón para evitar objetos grandes en la máquina virtual Java es que al asignar espacio, es fácil hacer que la recolección de basura se active por adelantado cuando todavía hay mucho espacio en la memoria, para obtener suficiente espacio continuo para colocar a ellos.

Y al copiar objetos, los objetos grandes significan una alta sobrecarga de copia de memoria.

La máquina virtual HotSpot proporciona el parámetro -XX:PretenureSizeThreshold, que especifica que los objetos más grandes que este valor de configuración se asignan directamente en la generación anterior. El propósito de esto es evitar la copia de ida y vuelta entre el área de Eden y las dos áreas de Survivor, lo que resulta en un gran número de operaciones de copia de memoria.

El propósito de hacer esto: 1. Evitar una gran cantidad de copia de memoria, 2. Evitar la recolección de basura por adelantado, obviamente hay espacio para la asignación de memoria.

Los objetos se asignan primero en el área de Eden

En la mayoría de los casos, los objetos se asignan en el área Eden de la generación joven. Cuando el área de Eden no tiene suficiente espacio para asignar, la máquina virtual iniciará un GC menor.

Los sobrevivientes a largo plazo ingresan al área de ancianos

La mayoría de los recopiladores en la máquina virtual HotSpot utilizan la recopilación generacional para administrar la memoria del montón, por lo que cuando se recicla la memoria, debe poder decidir qué objetos supervivientes deben colocarse en la generación joven y qué objetos supervivientes deben colocarse en la generación anterior. Para hacer esto, la máquina virtual define un contador de edad del objeto (Age) para cada objeto, que se almacena en el encabezado del objeto.

inserte la descripción de la imagen aquí

Si el objeto todavía está vivo después del primer GC menor después de nacer en Eden, y Survivor puede acomodarlo, se moverá al espacio Survivor y la edad del objeto se establecerá en 1. Cada vez que el objeto sobrevive un GC menor en el área Survivor, la edad aumenta en 1, y cuando su edad aumenta a un cierto nivel (el valor predeterminado del recolector de basura concurrente es 15), y el CMS es 6, se promoverá al antiguo generación.

Determinación dinámica de la edad del objeto
fondo de nacimiento

La JVM controla la antigüedad de la promoción a través del parámetro -XX:MaxTenuringThreshold. Cada vez que se pasa un GC, la antigüedad aumentará en uno y la antigüedad máxima se puede ingresar en el área Antiguo. El valor máximo es 15 (porque la JVM usa 4 bits para representar la edad del objeto). Establezca un valor MaxTenuringThreshold fijo como criterio de promoción. Surgen los siguientes problemas:

1. Si MaxTenuringThreshold se configura demasiado grande, los objetos que deben promoverse permanecerán en el área de Supervivientes hasta que se desborde el área de Supervivientes. Este es el mecanismo de envejecimiento de los objetos.

2. Si MaxTenuringThreshold se establece demasiado pequeño, la promoción prematura significa que los objetos no se pueden reciclar por completo en el área joven y una gran cantidad de objetos a corto plazo se promoverán al área antigua. El espacio en el área antigua crecerá rápidamente. , provocando GC mayor frecuentes, y el reciclaje generacional perderá su sentido Afecta gravemente el rendimiento del GC.

solución

Para adaptarse mejor al estado de la memoria de diferentes programas, la máquina virtual no siempre requiere que la edad del objeto deba alcanzar MaxTenuringThreshold para ser promovido a la generación anterior. Si la suma de los tamaños de todos los objetos de la misma edad en el espacio Superviviente es mayor que la mitad del espacio Superviviente, la edad Los objetos mayores o iguales a esta edad pueden ingresar directamente a la edad avanzada sin esperar la edad requerida en MaxTenuringThreshold.

Garantía de asignación de espacio

Antes de que ocurra Minor GC, la máquina virtual primero verifica si el espacio continuo máximo disponible en la generación anterior es mayor que el espacio total de todos los objetos en la nueva generación. Si esta condición es verdadera, entonces Minor GC puede garantizar la seguridad. De lo contrario, la máquina virtual verifica si el valor de configuración de HandlePromotionFailure permite la falla de garantía. Si está permitido, continuará verificando si el espacio continuo máximo disponible en la generación anterior es mayor que el tamaño promedio de los objetos promovidos a la generación anterior. Si es mayor, intentará realizar un GC menor. Aunque esto La GC menor es riesgosa, si la garantía falla, se realizará una GC completa; si es menor que, o si la configuración de HandlePromotionFailure no permite el riesgo, también se debe realizar una GC completa en este momento.

Supongo que te gusta

Origin blog.csdn.net/qq_43358469/article/details/131391777
Recomendado
Clasificación