1. Tipo de referencia (excluyendo una fuerte referencia)
Se puede entender que la subclase directa de referencia es procesada por JVM, por lo que no tiene ningún efecto para heredar directamente el tipo de referencia en el código. Solo puede ser heredado de su subclase. Los tipos de subclase correspondientes incluyen los siguientes. (Ignore los que no se usan en Java, como Jnireference)
Softreference
Referencia débil
Referencia final
Fantomreferencia
El tipo de referencia anterior también se menciona en el Javadoc correspondiente. FinalReference está especialmente diseñado para el método Finalize, y hay varios otros escenarios de aplicación específicos. Entre ellos, Softreference se usa en los cachés relacionados con la memoria, la referencia débil se usa en la mayoría de los escenarios relacionados con el reciclaje. Phantomreference se usa en escenarios de devolución de llamada para el reciclaje de objetos de empaque (como la detección de fuga de recursos).
Puede ver directamente la información de la subclase de varios tipos en el IDE para comprender qué escenarios se utilizan en la mayoría de los marcos heredando los tipos correspondientes, para que podamos realizar el procesamiento de selección de tipos.
2. Constructor de referencia
Proporciona dos constructores internamente, uno con una cola y la otra sin una cola. El significado de la cola es que podemos monitorear esta cola externamente. Es decir, si un objeto está a punto de ser reciclado, el objeto de referencia correspondiente se colocará en esta cola. Cuando obtenemos la referencia, podemos hacer algunas transacciones más.
Si no lo hace, solo puede entrenar el objeto de referencia continuamente, y juzgar si Get Inside Devuelve nulo (el objeto Phantomreference no puede hacer esto, el Get siempre devuelve nulo, por lo que solo tiene un constructor con una cola). Ambos métodos tienen escenarios de uso correspondientes, dependiendo de la aplicación real. Por ejemplo, en Weakhashmap, elige consultar los datos de la cola para determinar si algún objeto será reciclado. Para ThreadLocalMap, se usa para determinar si Get () es nulo para el procesamiento.
El constructor correspondiente es el siguiente:
Referencia (t referencia) {this (referente, nulo);} referencia (t reference, referencequeue <? Super t> queue) {this.referent = referent; this.queue = (queue == nulo)? Referencequeue.null: cola;}La cola nula aquí puede entenderse como una cola que no requiere ningún procesamiento de los datos en su cola. Y no accederá a ningún dato dentro de él.
En el objeto anterior, la referencia representa el objeto que hace referencia, es decir, el objeto en el que debemos estar envueltos cuando lo construimos. La definición de que el objeto está a punto de ser reciclado significa que este objeto no tiene otra referencia, excepto por referencia (no que realmente no se hace referencia, pero la accesibilidad GCROOT no se puede decir para evitar el problema de la referencia circular).
Una cola es la cola a notificar cuando el objeto se recicla. Cuando el objeto se recicla, todo el objeto de referencia (no el objeto reciclado) se colocará en la cola, y luego los programas externos pueden obtener los datos correspondientes al monitorear esta cola.
3. Referencequeue y cadena de referencia de referencia
La cola aquí es nominalmente una cola, pero no hay una estructura de almacenamiento real en el interior. Su almacenamiento depende de la relación entre los nodos internos. Se puede entender que la cola es una estructura similar a una lista vinculada, y el nodo aquí es en realidad la referencia en sí. Se puede entender que la cola es un contenedor para una lista vinculada, que solo almacena el nodo principal actual, y los nodos posteriores mantienen los nodos de referencia a través de sí mismo.
Valor de estado de referencia
Cada objeto de referencia tiene una descripción del estado correspondiente, es decir, se describe a sí mismo y al objeto envuelto actualmente, para la conveniencia de consultar, posicionar o procesar.
1. Activo: estado activo, es decir, el objeto correspondiente es un estado de referencia fuerte y no se ha reciclado. En este estado, el objeto no se colocará en la cola. En este estado, el siguiente es nulo, y la cola es la cola a la que se define cuando se define.
2. Pendiente: Prepárese para ponerlo en la cola. En este estado, los objetos a procesar se colocarán uno por uno en la cola. Durante esta ventana de tiempo, los objetos correspondientes están en el estado pendiente. No importa qué referencia, si ingresa a este estado, puede pensar que en el estado correspondiente, el siguiente es en sí mismo (establecido por JVM), y la cola es la cola referenciada cuando se define.
3. Enqueado: el objeto correspondiente ya debe reciclar, y el objeto de referencia correspondiente se ha colocado en la cola. El hilo externo está listo para consultar la cola para obtener los datos correspondientes. En este estado, el siguiente es el siguiente objeto que se procesará, y la cola es el objeto de identificación especial enqueado.
4. Inactivo: es decir, este objeto se ha recuperado de la cola desde el exterior y ha sido procesado. Eso significa que este objeto de referencia se puede reciclar, y el objeto encapsulado internamente también se puede reciclar (la operación de reciclaje real depende de si se llama la acción clara). Se puede entender que aquellos que ingresan a este estado deben ser reciclados.
JVM no necesita definir el valor de estado para determinar en qué estado se encuentra la referencia correspondiente. Solo necesita calcular a continuación y cola para emitir juicios.
4. ReferenceQueue#Head
Siempre guarde el último nodo que se procesará en la cola actual. Puede considerar la cola como una cola de primera entrada. Cuando entra un nuevo nodo, se adopta la siguiente lógica.
newe.next = head; head = newe;
Luego, al obtener, use la lógica correspondiente
tmp = head; head = tmp.next; return tmp;
V. Referencia#Siguiente
Es decir, describa el siguiente nodo almacenado por el nodo de referencia que está a punto de ser procesado. Pero el siguiente solo tendrá sentido cuando se coloque en la cola. Para describir el valor de estado correspondiente, después de colocarse en la cola, su cola ya no se referirá a la cola. En cambio, se referirá a un enqueado especial. Debido a que se ha colocado en la cola, no se colocará nuevamente en la cola.
6. Referente#Referente
Es decir, describa el objeto real referenciado por la referencia actual, que se procesará cuidadosamente como se indica en la anotación. Es decir, cuando esta cosa se reciclará, y si se recicla, se establecerá directamente en NULL, y los programas externos pueden aprender del objeto de referencia en sí (en lugar de referente) que se produce el comportamiento de reciclaje.
7. ReferenceQueue#Enqueue pendiente de referencia Enqueue
Este proceso es el proceso del objeto de referencia desde activo-> pendiente-> enqueado. Este método es procesar el objeto que maneja el estado pendiente como un estado ascendido. El proceso correspondiente es la lógica anterior, es decir, un nodo está encicado, y el código correspondiente es el siguiente.
r.queue = enqueuel; r.next = (cabeza == nulo)? r: cabeza; cabeza = r; queuelchent ++; lock.notifyall ();
El último Nitify significa notificar al programa externo que bloquea la cola actual antes. (Es decir, el objeto pendiente no se ha obtenido antes)
8. Referencia#intentehandlepending
Es decir, maneja el cambio del objeto de referencia de activo a estado pendiente. Dentro del objeto de referencia, hay un campo estático, y su declaración correspondiente es la siguiente:
/* Lista de referencias esperando ser enqueadas. El coleccionista agrega * referencias a esta lista, mientras que el hilo de manejo de referencia los elimina *. Esta lista está protegida por el objeto de bloqueo anterior. La lista * usa el campo descubierto para vincular sus elementos. */referencia estática privada <S Object> Pending = null;
Se puede entender que JVM pondrá el objeto para procesarse en este campo estático cuando GC. Al mismo tiempo, otro campo descubierto representa el siguiente objeto del objeto a procesar. Es decir, se puede entender que el objeto a procesar también es una lista vinculada. Está en cola a través del descubrimiento. Solo necesita seguir pendiente, y luego obtener continuamente el siguiente objeto a través del descubrimiento. Debido a que ambos hilos pueden acceder a este objeto pendiente, es necesario usar el procesamiento de bloqueo.
El proceso de procesamiento correspondiente es el siguiente:
if (pendiendo! = nulo) {r = pendiente; // 'instanciaf' podría tirar a veces deMemoryError //, así que haz esto antes de no retirarte 'r' de la cadena 'pendiente' ... c = r instancia de limpiador? (Limpiador) r: nulo; // desink 'r' de la cadena 'pendiente' pendiente = R.Descubred; r.discovered = null;} // Enqueue el objeto de procesamiento, es decir, ingresa a la referencia de estado de enquejado <? super objeto> q = r.queue; if (q! = referencequeue.null) q.enqueue (r);9. Referencia#Borrar
Borre el objeto original referenciado por el objeto de referencia, de modo que ya no se pueda acceder al objeto original a través del método get (). De la idea de diseño correspondiente, dado que ha ingresado al objeto de cola, significa que el objeto correspondiente debe reciclarse porque no es necesario acceder nuevamente al objeto original. El JVM no llamará a este método, y JVM borra directamente la referencia correspondiente a través de las operaciones de campo, y su implementación específica es consistente con el método actual.
La semántica de Clear es anular la referencia.
Después de que el objeto WeakReference ingresa a la cola, la referencia correspondiente es nula.
Softreference Object, si el objeto no ingresa a la cola cuando la memoria es suficiente, la referencia correspondiente no será nula. Si necesita ser procesado (no suficiente memoria u otras políticas), la referencia correspondiente se establece en NULL y luego ingrese la cola.
Objeto FinalReference, debido a que necesita llamar a su objeto finalizar, incluso si su referencia se ingresa en una cola, su referencia no será nula, es decir, no se borrará.
El objeto Phantomreference, porque la implementación para devolver nulo, no es muy útil. Porque no se borrará independientemente de si es enqueue o no.
10. Hilo de enqueue de referencia -Handler
Como se mencionó anteriormente, JVM establecerá que el objeto se procese en el objeto pendiente, por lo que debe haber un hilo para realizar operaciones continuas de Enqueue. Este hilo se refiere al hilo del procesador, y su prioridad es max_priority, es decir, la más alta. El proceso de inicio correspondiente se crea inicialización estática, que puede entenderse como cuando se usa cualquier objeto o clase de referencia, este hilo se creará y se iniciará. El código correspondiente es el siguiente:
static {ThreadGroup tg = Thread.CurrentThread (). GetThreadGroup (); para (ThreadGroup tgn = tg; tgn! = null; tg = tgn, tgn = tg.getParent ()); Handler de subprocesos = nuevo referenceHandler (TG, "Handler de referencia"); / * Si hubiera una prioridad especial de solo sistema mayor que * max_priority, se usaría aquí */ handler.setPriority (Thread.max_priority); handler.setdaemon (verdadero); handler.start ();}Su prioridad es la más alta, que puede entenderse como la necesidad de procesar continuamente objetos de referencia. Al imprimir un hilo en ejecución a través de Jstack, el controlador de referencia correspondiente se refiere al hilo inicializado aquí, como se muestra a continuación:
11. JVM Relacionado
En cada uno de los puntos de procesamiento anteriores, están relacionados con el proceso de reciclaje JVM. Es decir, se cree que el proceso GC funcionará junto con la referencia correspondiente. Por ejemplo, utilizando el colector CMS, el proceso previo está involucrado en todo el proceso mencionado anteriormente, y el procesamiento de comentario de Softreference, etc. Al mismo tiempo, varios procesos del objeto de referencia también deben estar relacionados con el tipo específico. El procesamiento JVM correspondiente utiliza el código C ++, por lo que debe resolverse cuidadosamente.
12. Resumen
Al igual que el objeto FinalReference, toda la referencia y referencia de referencia son un grupo de grupos de procesamiento que trabajan juntos. Para garantizar diferentes semánticas de referencia, el proceso relacionado con JVM GC finalmente se realiza para diferentes escenarios y diferentes niveles de referencia.
Además, porque directamente usar referencias y abrir hilos para monitorear las colas es demasiado problemático y complicado. Puede consultar FinalizableReferenceue implementado por Google Guava y el objeto Finalizableeference correspondiente. El proceso de procesamiento se puede simplificar un poco. Lo anterior es todo el contenido de este artículo, y espero que brinde ayuda para el aprendizaje o el trabajo de todos.