Cuando se trata de recolección de basura (GC), muchas personas lo asociarán naturalmente con Java. En Java, los programadores no necesitan preocuparse por la asignación de memoria dinámica y la recolección de basura, todo esto se deja en el JVM para manejar.
Como su nombre indica, la recolección de basura es liberar el espacio ocupado por la basura. Entonces, en Java, ¿qué tipo de objetos se considerarán "basura"? Entonces, cuando algunos objetos se determinan que son basura, ¿qué estrategia debe usarse para reciclar (espacio libre)? ¿Cuáles son los recolectores de basura típicos en las máquinas virtuales comerciales actuales? Discutamos estos temas uno por uno. Aquí está el esquema del directorio de este artículo:
¿Cómo determinar si un objeto es "basura"?
Algoritmo de recolección de basura típico recolectora de basura típica
1. ¿Cómo determinar si un objeto es "basura"?
En esta sección, primero entendemos la pregunta más básica: si determinamos que un objeto es "basura"? Dado que la tarea del recolector de basura es reciclar el espacio ocupado por el objeto de basura para usar por objetos nuevos, ¿cómo determina el recolector de basura que un objeto es "basura"? Es decir, cómo juzgar que un objeto puede reciclarse.
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.
Este método se caracteriza por su simple implementación y alta eficiencia, pero no puede resolver el problema de las referencias circulares, por lo que este método no se adopta en Java (Python utiliza el método de conteo de referencias). Mira el siguiente código:
public class Main {public static void main (string [] args) {myObject Object1 = new MyObject (); MyObject Object2 = new MyObject (); object1.object = object2; object2.Object = object1; objeto1 = nulo; objeto2 = nulo; }} clase MyObject {Public Object Object = Null;}Las dos últimas oraciones asignan Object1 y Object2 a NULL, lo que significa que los objetos señalados por Object1 y Object2 ya no son accesibles, pero debido a que se refieren entre sí, su recuento de referencia no es 0, entonces el recolector de basura nunca los reciclará.
Para resolver este problema, el método de análisis de accesibilidad se adopta en Java. 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.
En cuanto a cómo se opera el método de análisis de accesibilidad, todavía no lo he entendido muy claramente. Si algún amigo es más claro, por favor dame algunos consejos.
Veamos un ejemplo a continuación:
Object ABJ = New Object (); Object Bobj = New Object (); Object Cobj = New Object (); Aobj = Bobj; Aobj = Cobj; Cobj = Null; Aobj = Null;
¿Qué línea puede hacer que un objeto sea reciclable? El código en la línea 7 hará que los objetos se conviertan en objetos reciclables. En cuanto a por qué se deja a los lectores que piensen por sí mismos.
Echemos un vistazo a otro ejemplo:
String str = new String ("Hello"); Softreference <String> sr = new Softreference <String> (new String ("Java")); WeakReference <String> wr = new WeakReference <String> (new String ("World"));¿Cuál de estas tres oraciones hará que un objeto de cadena sea reciclable? La oración 2 y 3, y la oración 2 determinarán el objeto de cadena como un objeto reciclable cuando no hay memoria insuficiente, y en la tercera oración, el objeto de cadena se determinará como un objeto reciclable en cualquier caso.
Finalmente, resumamos las situaciones comunes en las que los objetos se juzgan como objetos reciclables que generalmente se encuentran:
1) Muestre el valor de una referencia a NULL o apunte la referencia que ya ha señalado un objeto a un nuevo objeto, como el siguiente código:
Object obj = new Object (); obj = null; obje obj1 = new Object (); Obj Obj2 = New Object (); obj1 = obj2;
2) La referencia local al objeto señaló, como el siguiente código:
Void Fun () {...... for (int i = 0; i <10; i ++) {object obj = new Object (); System.out.println (obj.getClass ()); }}Cada vez que se ejecuta el bucle, el objeto generado se convertirá en un objeto reciclable.
3) Solo las referencias débiles están asociadas con objetos, como:
Débilreference <string> wr = new WeakReference <String> (new String ("World"));2. Algoritmo típico de recolección de basura
Después de determinar qué basura se puede reciclar, el recolector de basura debe hacer es comenzar la recolección de basura, pero un problema involucrado es: cómo recolectar basura de manera eficiente. Dado que la especificación de la máquina virtual Java no hace regulaciones claras sobre cómo implementar un recolector de basura, las máquinas virtuales de cada fabricante pueden implementar un recolector de basura de diferentes maneras, por lo que solo las ideas centrales de varios algoritmos comunes de recolección de basura se discuten aquí.
1. Algoritmo de mark-sweep (Mark-Clar)
Este es el algoritmo de recolección de basura más básico. La razón por la que se dice que es la más básica es que es la más fácil de implementar y la idea más simple. El algoritmo de limpieza de marcas se divide en dos etapas: la etapa de marcado y la etapa de limpieza. La tarea de la etapa de marcado es marcar todos los objetos que necesitan ser reciclados, y la etapa de compensación es reciclar el espacio ocupado por los objetos marcados. El proceso específico se muestra en la figura a continuación:
Se puede ver fácilmente en la figura que el algoritmo de limpieza de marcas es más fácil de implementar, pero existe un problema grave de que es fácil generar fragmentos de memoria. Demasiados fragmentos pueden causar la incapacidad de encontrar suficiente espacio al asignar espacio para objetos grandes en el proceso posterior, y activar una nueva acción de recolección de basura de antemano.
2. Algoritmo de copia (copia)
Para resolver las deficiencias del algoritmo Mark-Sweep, se propuso el algoritmo de copia. Divide la memoria disponible en dos piezas de igual tamaño por capacidad, usando solo una pieza a la vez. Cuando se use esta memoria, copie el objeto de vida muerto a otra pieza y luego limpie el espacio de memoria usado a la vez, para que los problemas de fragmentación de memoria no ocurran. El proceso específico se muestra en la figura a continuación:
Aunque este algoritmo es fácil de implementar, eficiente para ejecutar y no es fácil de generar fragmentación de memoria, es costoso usar el espacio de memoria porque la memoria que se puede usar se reduce a la mitad de la original.
Obviamente, la eficiencia del algoritmo de copia tiene mucho que ver con el número de objetos sobrevivientes. Si hay muchos objetos sobrevivientes, la eficiencia del algoritmo de copia se reducirá considerablemente.
3. Algoritmo de compacto (marca de marca)
Para resolver las deficiencias del algoritmo de copia y hacer uso completo del espacio de memoria, se propone el algoritmo de marca compacto. El algoritmo marca lo mismo que Mark-Sweep, pero después de completar la marca, no limpia directamente los objetos reciclables, sino que mueve todos los objetos vivos a un extremo y luego limpia la memoria fuera del límite final. El proceso específico se muestra en la figura a continuación:
4. Algoritmo de colección generacional
El algoritmo de recolección de generación es actualmente utilizado por la mayoría de los recolectores de basura JVM. Su idea central es dividir la memoria en varias regiones diferentes de acuerdo con el ciclo de vida de la supervivencia del objeto. En términos generales, el área del montón se divide en la antigua generación y la generación joven. La característica de la antigua generación es que solo un pequeño número de objetos necesita reciclarse cada vez que se recolecte la basura, mientras que la característica de la nueva generación es que una gran cantidad de objetos deben reciclar cada vez que se recolecte la basura. Luego, el algoritmo de recolección más adecuado se puede adoptar de acuerdo con las características de diferentes generaciones.
En la actualidad, la mayoría de los recolectores de basura adoptan el algoritmo de copia para la nueva generación, porque en la nueva generación, la mayoría de los objetos deben reciclar cada vez que se recolecte la recolección de basura, lo que significa que el número de operaciones que deben copiarse es relativamente pequeño, pero en realidad, el espacio de la nueva generación no está dividida de acuerdo con un rato de 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 el Edén 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.
3. Típico recolector de basura
El algoritmo de recolección de basura es la base teórica del reciclaje de memoria, y el recolector de basura es la implementación específica del reciclaje de memoria. La siguiente es una descripción de varios coleccionistas de basura proporcionados por la máquina virtual del punto de acceso (JDK 7). Los usuarios pueden combinar coleccionistas utilizados en cada época de acuerdo con sus propias necesidades.
1.Serial/Serial Old
El coleccionista antiguo serial/serie es el coleccionista más básico y antiguo. Es un colector de hilo único y debe pausar todos los hilos de los usuarios cuando realiza recolección de basura. El coleccionista en serie es un coleccionista para la nueva generación, utilizando el algoritmo de copia, y el colector antiguo en serie es un coleccionista para la generación anterior, utilizando el algoritmo de marca compacto. Su ventaja es que es simple y eficiente, pero su desventaja es que causará pausas a los usuarios.
2. Parnew
El coleccionista Parnew es una versión de múltiples subprocesos del coleccionista en serie que utiliza múltiples hilos para la recolección de basura.
3. Buscador paralelo
El coleccionista de Scavenge Parallel es una nueva generación de coleccionistas multiproceso (coleccionistas paralelos). No necesita pausar otros hilos de usuario durante el reciclaje. Utiliza el algoritmo de copia. Este coleccionista es diferente de los dos primeros coleccionistas. Es principalmente para lograr un rendimiento controlado.
4. Paralelo viejo
Parallel Old es una versión antigua del coleccionista de Scavenge Parallel (coleccionista paralelo) utilizando algoritmos multiproceso y compacto de marca.
5.cms
El coleccionista CMS (corriente de marca actual) es un coleccionista destinado a obtener el tiempo de pausa de recuperación más corto. Es un coleccionista concurrente que utiliza el algoritmo de mark-sweep.
6.G1
El coleccionista G1 es el logro más de vanguardia en el desarrollo de tecnología de coleccionistas actual. Es un coleccionista para aplicaciones del lado del servidor que pueden hacer uso completo de entornos de múltiples CPU y múltiples núcleos. Por lo tanto, es un coleccionista paralelo y de concurrencia, y puede construir un modelo de tiempo de pausa predecible.
Aquí hay algunas cosas sobre la asignación de memoria:
En una dirección general, la asignación de memoria de objetos se asigna en el montón. Los objetos se asignan principalmente en la nueva generación del espacio del Edén y desde el espacio, y en casos raros se asignarán directamente en la vejez. Si el espacio de la nueva generación de espacio de Edén y desde el espacio es insuficiente, se iniciará un GC. Si se realiza el GC, el espacio Eden y desde el espacio puede acomodar el objeto y se colocan en el espacio del Edén y desde el espacio.
Durante el proceso de GC, los objetos sobrevivientes en el espacio de Edén y desde el espacio se trasladarán al espacio, y luego se limpiarán el espacio Eden y desde el espacio. Si el espacio no puede ser suficiente para almacenar un objeto durante la limpieza, moverá el objeto a la vejez. Después de GC, se usan espacio de Edén y espacio. La próxima vez que GC, el objeto sobreviviente se copiará desde el espacio, y el bucle se repetirá. Cuando un objeto escapa a GC una vez en el área de sobrevivientes, la edad de su objeto se incrementará en 1. Por defecto, si el objeto alcanza los 15 años, pasará a la mediana edad de la vejez.
En términos generales, los objetos grandes se asignarán directamente a la vejez. Los llamados objetos grandes se refieren a objetos que requieren una gran cantidad de espacio de almacenamiento continuo. El tipo más común de objetos grandes son las matrices grandes, como:
byte [] data = new Byte [4*1024*1024]
Este tipo de espacio de almacenamiento generalmente se asignará directamente en los ancianos.
Por supuesto, las reglas de asignación no son 100% fijas, lo que depende del tipo de combinación de recolector de basura y los parámetros relevantes del JVM se están utilizando actualmente.
Lo anterior es todo el contenido de este artículo. Espero que sea útil para el aprendizaje de todos y espero que todos apoyen más a Wulin.com.